Putting It All Back Together

Throughout all the data analysis we’ve done, the datasets have become more fragmented - lexical recall, gist, and eye tracking datasets. I want to put them all together in one whole dataset again so we can perform some analyses more efficiently (particularly correlations). The only thing I need to remember is we’ll have a new column called eye_exclude and if it is set to TRUE it means we can’t include that row in any analysis relating to eye gaze (usually because that trial was less than 25% looking).

# Libraries
library(tidyverse)
Warning message:
In as.POSIXlt.POSIXct(Sys.time()) :
  unknown timezone 'zone/tz/2017c.1.0/zoneinfo/America/Los_Angeles'
library(lme4)
library(lmerTest)
library(scales)
library(viridis)
library(agricolae) 
library(GGally)
# Load lex and eye data
cleanlexdata <- read_csv("cleandata.csv") %>%
  select(-(forehead:total))
cleaneyedata <- read_csv("cleanpercentdata.csv") %>%
  spread(aoi,percent) %>%
  add_column(eye_exclude = FALSE)
# What rows were removed from the eye data back in 03eyegaze? Let's add back in
# With a new column - eye_exclude
removed <- anti_join(cleanlexdata, cleaneyedata) %>%
  add_column(eye_exclude = TRUE)
eyelexdata <- bind_rows(cleaneyedata, removed)
# Load gist data
gist <- read_csv('gist_indiv.csv', col_types = cols(
  participant = col_character(),
  gist.fw1 = col_integer(),
  gist.rv2 = col_integer(),
  gist.fw3 = col_integer(),
  gist.rv4 = col_integer()
)) %>%
  gather(video, gist, gist.fw1:gist.rv4) %>%
  mutate(video = str_sub(video,6,8))
# Presto, our full reunified dataset - 'fulldata'
# But I want to remove columns I don't want anymore
fulldata <- left_join(eyelexdata, gist) %>%
  select(-moutheye, -facechest, -face, -chest)

Group Changes and Participant Tables

We have some changes to make to the groups. First, fix Josh as learning ASL when he was 6. Next, drop the DeafNative Group and reclassify all who learned ASL < 3.9 as DeafEarly and ASL => 4.0 as DeafLate.

# Change Josh's AoASL to 6
fulldata <- fulldata %>%
  mutate(aoasl = as.double(aoasl)) %>%
  mutate(aoasl = case_when(
    participant == "Josh" ~ 6,
    TRUE ~ aoasl
  ))
# Reclassify Groups
fulldata <- fulldata %>%
  mutate(maingroup = case_when(
    hearing == "Deaf" & aoasl < 4 ~ "DeafEarly",
    hearing == "Deaf" & aoasl >= 4 ~ "DeafLate",
    maingroup == "HearingLateASL" ~ "HearingLate",
    maingroup == "HearingNoviceASL" ~ "HearingNovice"
  ))
# Create Participant Demographics Table
participant_info <- fulldata %>%
  select(-(acc:gist)) %>%
  select(-(video:direction)) %>%
  distinct() %>% 
  group_by(maingroup) %>%
  summarise(n = n(),
            age_mean = mean(age),
            age_sd = sd(age),
            aoasl_mean = mean(aoasl),
            aoasl_sd = sd(aoasl),
            signyrs_mean = mean(signyrs),
            signyrs_sd = sd(signyrs),
            selfrate_mean = mean(selfrate),
            selfrate_sd = sd(selfrate)) %>%
  ungroup() %>%
  mutate_if(is.double, funs(round(., 2))) %>%
  mutate(age = paste(age_mean, "±", age_sd, sep = " "),
         aoasl = paste(aoasl_mean, "±", aoasl_sd, sep = " "),
         signyrs = paste(signyrs_mean, "±", signyrs_sd, sep = " "),
         selfrate = paste(selfrate_mean, "±", selfrate_sd, sep = " ")) %>%
  select(-(age_mean:selfrate_sd)) %>%
  print()

Participant ANOVAs

Below are the ANOVA outputs for participant demographics, and LSDs for each.

Participants’ age

            Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup    3   1810   603.3   14.29 8.75e-07 ***
Residuals   48   2026    42.2                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
                            difference pvalue signif.        LCL       UCL
DeafEarly - DeafLate         -2.757143 0.2591         -7.6115142  2.097228
DeafEarly - HearingLate       4.683333 0.0688       . -0.3759532  9.742620
DeafEarly - HearingNovice    13.350000 0.0000     ***  8.1645274 18.535473
DeafLate - HearingLate        7.440476 0.0054      **  2.3015110 12.579441
DeafLate - HearingNovice     16.107143 0.0000     *** 10.8439015 21.370384
HearingLate - HearingNovice   8.666667 0.0025      **  3.2138538 14.119480

Participants’ AoASL

            Df Sum Sq Mean Sq F value Pr(>F)    
maingroup    3 2553.9   851.3   89.98 <2e-16 ***
Residuals   48  454.1     9.5                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
                             difference pvalue signif.        LCL        UCL
DeafEarly - DeafLate        -10.3333333 0.0000     *** -12.631552  -8.035114
DeafEarly - HearingLate     -16.5833333 0.0000     *** -18.978566 -14.188101
DeafEarly - HearingNovice   -16.9696970 0.0000     *** -19.424670 -14.514724
DeafLate - HearingLate       -6.2500000 0.0000     ***  -8.682955  -3.817045
DeafLate - HearingNovice     -6.6363636 0.0000     ***  -9.128155  -4.144572
HearingLate - HearingNovice  -0.3863636 0.7648          -2.967905   2.195177

Participants’ Sign Yrs

            Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup    3   7032  2344.1   59.37 3.52e-16 ***
Residuals   48   1895    39.5                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
                            difference pvalue signif.       LCL      UCL
DeafEarly - DeafLate          7.585714 0.0021      **  2.890730 12.28070
DeafEarly - HearingLate      21.050000 0.0000     *** 16.156828 25.94317
DeafEarly - HearingNovice    30.359091 0.0000     *** 25.343876 35.37431
DeafLate - HearingLate       13.464286 0.0000     ***  8.494052 18.43452
DeafLate - HearingNovice     22.773377 0.0000     *** 17.682947 27.86381
HearingLate - HearingNovice   9.309091 0.0009     ***  4.035314 14.58287

Participants’ Self-Rating

            Df Sum Sq Mean Sq F value Pr(>F)    
maingroup    3  30.71  10.237   72.37 <2e-16 ***
Residuals   48   6.79   0.141                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
                            difference pvalue signif.         LCL       UCL
DeafEarly - DeafLate          0.000000 1.0000         -0.28101502 0.2810150
DeafEarly - HearingLate       0.375000 0.0132       *  0.08212263 0.6678774
DeafEarly - HearingNovice     1.954545 0.0000     ***  1.65436329 2.2547276
DeafLate - HearingLate        0.375000 0.0146       *  0.07751010 0.6724899
DeafLate - HearingNovice      1.954545 0.0000     ***  1.64986133 2.2592296
HearingLate - HearingNovice   1.579545 0.0000     ***  1.26388721 1.8952037

Gist & Lexical Recall Data

Tables & Charts

Let’s generate a table for lexical recall and gist for forward vs. reversed stories.

lexgist_info <- fulldata %>%
  group_by(maingroup, direction) %>%
  summarise(lex_mean = mean(acc, na.rm = TRUE),
            lex_sd = sd(acc, na.rm = TRUE),
            gist_mean = mean(gist),
            gist_sd = sd(gist)) %>%
  ungroup() %>%
  mutate_if(is.double, funs(round(., 2))) %>% 
  mutate(lex = paste(lex_mean, "±", lex_sd, sep = " "),
         gist = paste(gist_mean, "±", gist_sd, sep = " ")) %>%
  select(-(lex_mean:gist_sd)) %>%
  gather(metric, value, lex:gist) %>%
  unite("metric", c(metric, direction), sep = "_") %>%
  spread(metric, value) %>%
  print()

And then bar charts too after that with error bars.

# Gist bar chart
gist_bar <- fulldata %>% select(participant, maingroup, direction, gist) %>%
  group_by(maingroup, participant, direction) %>%
  summarise(gist = mean(gist)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(gist),
            sd = sd(gist),
            count = n(),
            se = sd/sqrt(count))
ggplot(gist_bar, aes(x = maingroup, y = mean, fill = direction)) +
  geom_bar(stat = "identity", position = position_dodge()) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "Story Comprehension (Gist)", subtitle = "Error bars represent SE", x = "", y = "mean gist") +
  scale_y_continuous(labels = percent, limits = c(0,1))

# Lex bar chart
lex_bar <- fulldata %>% select(participant, maingroup, direction, acc) %>%
  group_by(maingroup, participant, direction) %>%
  summarise(acc = mean(acc, na.rm = TRUE)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(acc, na.rm = TRUE),
            sd = sd(acc, na.rm = TRUE),
            count = n(),
            se = sd/sqrt(count))
ggplot(lex_bar, aes(x = maingroup, y = mean, fill = direction)) +
  geom_bar(stat = "identity", position = position_dodge()) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "Lexical Recall", subtitle = "Error bars represent SE", x = "", y = "mean accuracy") +
  scale_y_continuous(labels = percent, limits = c(0,1)) +
  geom_hline(yintercept = .5, linetype = "dotted") +
  coord_cartesian(ylim = c(.5,1))

ANOVA Plan

Next, we’re going to do ANOVAs and ANCOVAs. We’ll always do it in this order. The first three ANOVAs will be followed by LSD of the four maingroups with uncorrected p-values.

  1. ANOVA with factors MainGroup & Direction
  2. ANOVA with factor MainGroup, for Forward only
  3. ANOVA with factor MainGroup, for Reverse only
  4. ANCOVA with factor Direction, and covariate AoASL and Age
  5. Regression with variables AoASL and Age, for Forward only
  6. Regression with variables AoASL and Age, for Reverse only.

I did not include Age as a covariate in the first 3 ANOVAs because they did not add to or change the model in any significant way.

Gist ANOVAs

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup            3  3.002   1.001  13.284 2.53e-07 ***
direction            1  5.310   5.310  70.491 4.10e-13 ***
maingroup:direction  3  0.896   0.299   3.965   0.0103 *  
Residuals           96  7.232   0.075                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only. Also a Kruskal-Wallis test. And Chi-Sq too.
            Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup    3  2.477  0.8256   16.11 2.23e-07 ***
Residuals   48  2.461  0.0513                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

    Kruskal-Wallis rank sum test

data:  gist by maingroup
Kruskal-Wallis chi-squared = 25.46, df = 3, p-value = 1.237e-05
Chi-squared approximation may be incorrect

    Pearson's Chi-squared test

data:  gist_chisq_fw
X-squared = 26.984, df = 6, p-value = 0.0001458
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value  Pr(>F)   
maingroup    3  1.421  0.4737   4.766 0.00548 **
Residuals   48  4.771  0.0994                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

    Kruskal-Wallis rank sum test

data:  gist by maingroup
Kruskal-Wallis chi-squared = 11.365, df = 3, p-value = 0.009907
Chi-squared approximation may be incorrect

    Pearson's Chi-squared test

data:  gist_chisq_rv
X-squared = 15.056, df = 6, p-value = 0.01982
  1. ANCOVA with factor Direction, and variables AoASL and Age.
                    Df Sum Sq Mean Sq F value   Pr(>F)    
direction            1  5.310   5.310  61.435 6.24e-12 ***
aoasl                1  1.435   1.435  16.602 9.50e-05 ***
age                  1  0.524   0.524   6.058   0.0156 *  
direction:aoasl      1  0.033   0.033   0.386   0.5360    
direction:age        1  0.216   0.216   2.493   0.1176    
aoasl:age            1  0.579   0.579   6.703   0.0111 *  
direction:aoasl:age  1  0.045   0.045   0.524   0.4707    
Residuals           96  8.298   0.086                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = gist ~ aoasl * age, data = filter(participant_data, 
    direction == "forward"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.64682 -0.04576  0.00158  0.12355  0.42535 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  1.0541328  0.2576559   4.091 0.000163 ***
aoasl       -0.0551054  0.0184504  -2.987 0.004431 ** 
age         -0.0016630  0.0074651  -0.223 0.824659    
aoasl:age    0.0015158  0.0005719   2.650 0.010863 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2599 on 48 degrees of freedom
Multiple R-squared:  0.3434,    Adjusted R-squared:  0.3023 
F-statistic: 8.366 on 3 and 48 DF,  p-value: 0.0001409
  1. Regression with variables AoASL and Age, for Reverse only.

Call:
lm(formula = gist ~ aoasl * age, data = filter(participant_data, 
    direction == "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.63610 -0.22752  0.02114  0.24941  0.61943 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept)  0.8059325  0.3217367   2.505   0.0157 *
aoasl       -0.0431909  0.0230392  -1.875   0.0669 .
age         -0.0058563  0.0093218  -0.628   0.5328  
aoasl:age    0.0008532  0.0007142   1.195   0.2381  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3245 on 48 degrees of freedom
Multiple R-squared:  0.1836,    Adjusted R-squared:  0.1326 
F-statistic: 3.598 on 3 and 48 DF,  p-value: 0.02002

Lexical Recall ANOVAs

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup            3 0.1175  0.0392   5.348  0.00189 ** 
direction            1 0.5211  0.5211  71.149 3.38e-13 ***
maingroup:direction  3 0.0294  0.0098   1.336  0.26731    
Residuals           96 0.7031  0.0073                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df  Sum Sq  Mean Sq F value Pr(>F)  
maingroup    3 0.04988 0.016626   2.984 0.0404 *
Residuals   48 0.26749 0.005573                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)  
maingroup    3 0.0970 0.03233   3.562 0.0209 *
Residuals   48 0.4356 0.00908                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value   Pr(>F)    
direction            1 0.5211  0.5211  69.354 5.72e-13 ***
aoasl                1 0.0431  0.0431   5.731   0.0186 *  
age                  1 0.0347  0.0347   4.621   0.0341 *  
direction:aoasl      1 0.0204  0.0204   2.716   0.1026    
direction:age        1 0.0094  0.0094   1.253   0.2658    
aoasl:age            1 0.0195  0.0195   2.602   0.1100    
direction:aoasl:age  1 0.0015  0.0015   0.202   0.6540    
Residuals           96 0.7213  0.0075                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = acc ~ aoasl * age, data = filter(participant_data, 
    direction == "forward"))

Residuals:
      Min        1Q    Median        3Q       Max 
-0.223429 -0.032150  0.004461  0.039614  0.205706 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.7878168  0.0743596  10.595 3.69e-14 ***
aoasl       -0.0045003  0.0053248  -0.845    0.402    
age          0.0017563  0.0021544   0.815    0.419    
aoasl:age    0.0001569  0.0001651   0.951    0.347    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.07501 on 48 degrees of freedom
Multiple R-squared:  0.1491,    Adjusted R-squared:  0.09593 
F-statistic: 2.804 on 3 and 48 DF,  p-value: 0.04966
  1. Regression with variables AoASL and Age, for Reverse only.

Call:
lm(formula = acc ~ aoasl * age, data = filter(participant_data, 
    direction == "reversed"))

Residuals:
      Min        1Q    Median        3Q       Max 
-0.243150 -0.053718  0.000822  0.061438  0.212639 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.8084021  0.0961239   8.410 5.33e-11 ***
aoasl       -0.0127774  0.0068833  -1.856   0.0696 .  
age         -0.0018529  0.0027850  -0.665   0.5090    
aoasl:age    0.0002782  0.0002134   1.304   0.1985    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.09696 on 48 degrees of freedom
Multiple R-squared:  0.1527,    Adjusted R-squared:  0.09977 
F-statistic: 2.884 on 3 and 48 DF,  p-value: 0.04527

AoA Correlations

Next, we want to look at correlations between AoA and Gist, and betwen AoA and Lexical Recall. Rain asked for forward and reversed separately (1) deaf only, (2) hearing only, and (3) both. Let’s make it work.

# Let's make participant-level data, and have forward/reversed in separate columns
lexgist_data <- fulldata %>%
  group_by(maingroup, participant, direction) %>%
  mutate(gist = mean(gist, na.rm = TRUE),
         lex = mean(acc, na.rm = TRUE)) %>%
  ungroup() %>%
  select(maingroup, participant, hearing, direction, aoasl, signyrs, age, gist, lex) %>%
  distinct() %>%
  gather(metric, value, gist:lex) %>%
  unite(metricvalue, c(metric, direction), sep = "_") %>%
  spread(metricvalue, value) %>%
  select(-participant, -maingroup)
lexgist_deaf <- lexgist_data %>% filter(hearing == "Deaf") %>% select(-hearing)
lexgist_hearing <- lexgist_data %>% filter(hearing == "Hearing") %>% select(-hearing)
lexgist_all <- lexgist_data %>% select(-hearing)
# Load awesome function to make correlation tables with stars for significance
# From: https://myowelt.blogspot.co.uk/2008/04/beautiful-correlation-tables-in-r.html
corstarsl <- function(x){ 
require(Hmisc) 
x <- as.matrix(x) 
R <- Hmisc::rcorr(x)$r 
p <- Hmisc::rcorr(x)$P 
## define notions for significance levels; spacing is important.
mystars <- ifelse(p < .001, "***", ifelse(p < .01, "** ", ifelse(p < .05, "* ", " ")))
## trunctuate the matrix that holds the correlations to two decimal
R <- format(round(cbind(rep(-1.11, ncol(x)), R), 2))[,-1] 
## build a new matrix that includes the correlations with their apropriate stars 
Rnew <- matrix(paste(R, mystars, sep=""), ncol=ncol(x)) 
diag(Rnew) <- paste(diag(R), " ", sep="") 
rownames(Rnew) <- colnames(x) 
colnames(Rnew) <- paste(colnames(x), "", sep="") 
## remove upper triangle
Rnew <- as.matrix(Rnew)
Rnew[upper.tri(Rnew, diag = TRUE)] <- ""
Rnew <- as.data.frame(Rnew) 
## remove last column and return the matrix (which is now a data frame)
Rnew <- cbind(Rnew[1:length(Rnew)-1])
return(Rnew) 
}
# Correlations for Deaf
print("DEAF Correlations - Pearson's r")
[1] "DEAF Correlations - Pearson's r"
#corstarsl(lexgist_deaf)
Hmisc::rcorr(as.matrix(lexgist_deaf))$r
                    aoasl     signyrs        age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.50188273  0.2569266   0.08266371   -0.25585943  0.14743346  -0.25601873
signyrs       -0.50188273  1.00000000  0.7005996   0.18321127   -0.01264108  0.27968505   0.06666998
age            0.25692660  0.70059955  1.0000000   0.27454460   -0.17264941  0.42997837  -0.12765634
gist_forward   0.08266371  0.18321127  0.2745446   1.00000000    0.01762269 -0.08155560  -0.09770666
gist_reversed -0.25585943 -0.01264108 -0.1726494   0.01762269    1.00000000  0.02667231   0.36021802
lex_forward    0.14743346  0.27968505  0.4299784  -0.08155560    0.02667231  1.00000000   0.35984892
lex_reversed  -0.25601873  0.06666998 -0.1276563  -0.09770666    0.36021802  0.35984892   1.00000000
print("DEAF Correlations - P-values")
[1] "DEAF Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_deaf))$P
                    aoasl      signyrs          age gist_forward gist_reversed lex_forward lex_reversed
aoasl                  NA 5.536857e-03 1.784812e-01    0.6698839    0.18035489  0.44533530   0.18007434
signyrs       0.005536857           NA 2.316796e-05    0.3414473    0.94810844  0.14172236   0.73113301
age           0.178481213 2.316796e-05           NA    0.1495001    0.37046625  0.01990877   0.50930544
gist_forward  0.669883883 3.414473e-01 1.495001e-01           NA    0.92770438  0.67406661   0.61409897
gist_reversed 0.180354888 9.481084e-01 3.704662e-01    0.9277044            NA  0.89076140   0.05492031
lex_forward   0.445335297 1.417224e-01 1.990877e-02    0.6740666    0.89076140          NA   0.05518766
lex_reversed  0.180074336 7.311330e-01 5.093054e-01    0.6140990    0.05492031  0.05518766           NA
cat(paste("","\n",""))
# Correlations for Hearing
print("HEARING Correlations - Pearson's r")
[1] "HEARING Correlations - Pearson's r"
#corstarsl(lexgist_hearing)
Hmisc::rcorr(as.matrix(lexgist_hearing))$r
                    aoasl     signyrs       age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.07887013 0.3468184  -0.15525565    0.07815751  0.02500269   0.01411303
signyrs       -0.07887013  1.00000000 0.9021947   0.57814670    0.28845748  0.36725658   0.20828810
age            0.34681845  0.90219468 1.0000000   0.44651473    0.30963454  0.30931753   0.20139593
gist_forward  -0.15525565  0.57814670 0.4465147   1.00000000    0.29502174  0.57154566   0.07645807
gist_reversed  0.07815751  0.28845748 0.3096345   0.29502174    1.00000000  0.35682374   0.57951176
lex_forward    0.02500269  0.36725658 0.3093175   0.57154566    0.35682374  1.00000000   0.36558339
lex_reversed   0.01411303  0.20828810 0.2013959   0.07645807    0.57951176  0.36558339   1.00000000
print("HEARING Correlations - P-values")
[1] "HEARING Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_hearing))$P
                  aoasl      signyrs          age gist_forward gist_reversed lex_forward lex_reversed
aoasl                NA 7.205586e-01 1.049514e-01  0.479339909   0.722986497 0.909841021  0.949040176
signyrs       0.7205586           NA 4.046899e-09  0.003857505   0.181932462 0.084723426  0.340222805
age           0.1049514 4.046899e-09           NA  0.032691671   0.150502508 0.150942632  0.356794880
gist_forward  0.4793399 3.857505e-03 3.269167e-02           NA   0.171744860 0.004385475  0.728786878
gist_reversed 0.7229865 1.819325e-01 1.505025e-01  0.171744860            NA 0.094647552  0.003755275
lex_forward   0.9098410 8.472343e-02 1.509426e-01  0.004385475   0.094647552          NA  0.086260140
lex_reversed  0.9490402 3.402228e-01 3.567949e-01  0.728786878   0.003755275 0.086260140           NA
cat(paste("","\n",""))
# Correlations for All
print("ALL Correlations - Pearson's r")
[1] "ALL Correlations - Pearson's r"
#corstarsl(lexgist_all)
Hmisc::rcorr(as.matrix(lexgist_all))$r
                    aoasl    signyrs        age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.7852245 -0.3136458   -0.3230903    -0.3922803 -0.08115845   -0.3394521
signyrs       -0.78522450  1.0000000  0.8314757    0.4956183     0.3356193  0.29698992    0.3182316
age           -0.31364575  0.8314757  1.0000000    0.4602616     0.1930257  0.36318284    0.1886432
gist_forward  -0.32309031  0.4956183  0.4602616    1.0000000     0.2712761  0.49279109    0.1521110
gist_reversed -0.39228034  0.3356193  0.1930257    0.2712761     1.0000000  0.21701819    0.4921550
lex_forward   -0.08115845  0.2969899  0.3631828    0.4927911     0.2170182  1.00000000    0.3800772
lex_reversed  -0.33945209  0.3182316  0.1886432    0.1521110     0.4921550  0.38007715    1.0000000
print("ALL Correlations - P-values")
[1] "ALL Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_all))$P
                     aoasl      signyrs          age gist_forward gist_reversed  lex_forward
aoasl                   NA 5.523138e-12 2.356068e-02 0.0194786567  0.0040239673 0.5673489939
signyrs       5.523138e-12           NA 2.309264e-14 0.0001870211  0.0150006737 0.0325116001
age           2.356068e-02 2.309264e-14           NA 0.0005965582  0.1703671221 0.0081373882
gist_forward  1.947866e-02 1.870211e-04 5.965582e-04           NA  0.0517394597 0.0002061625
gist_reversed 4.023967e-03 1.500067e-02 1.703671e-01 0.0517394597            NA 0.1222542968
lex_forward   5.673490e-01 3.251160e-02 8.137388e-03 0.0002061625  0.1222542968           NA
lex_reversed  1.382018e-02 2.149676e-02 1.804672e-01 0.2817023354  0.0002107074 0.0054478274
              lex_reversed
aoasl         0.0138201778
signyrs       0.0214967644
age           0.1804672184
gist_forward  0.2817023354
gist_reversed 0.0002107074
lex_forward   0.0054478274
lex_reversed            NA

I’m also including nicely formatted tables with *** indicators of significance for quick referencing. Order: Deaf, Hearing, All.

corstarsl(lexgist_deaf)
corstarsl(lexgist_hearing)
corstarsl(lexgist_all)

Scatterplot of Correlations

Let’s visualize what’s happening with the correlations here.

ggpairs(lexgist_data, columns = c(2:8), aes(color = hearing))

 plot: [1,1] [==------------------------------------------------------------------------]  2% est: 0s 
 plot: [1,2] [===-----------------------------------------------------------------------]  4% est: 9s 
 plot: [1,3] [=====---------------------------------------------------------------------]  6% est:12s 
 plot: [1,4] [======--------------------------------------------------------------------]  8% est:11s 
 plot: [1,5] [========------------------------------------------------------------------] 10% est:10s 
 plot: [1,6] [=========-----------------------------------------------------------------] 12% est: 9s 
 plot: [1,7] [===========---------------------------------------------------------------] 14% est: 9s 
 plot: [2,1] [============--------------------------------------------------------------] 16% est: 9s 
 plot: [2,2] [==============------------------------------------------------------------] 18% est: 9s 
 plot: [2,3] [===============-----------------------------------------------------------] 20% est: 9s 
 plot: [2,4] [=================---------------------------------------------------------] 22% est: 9s 
 plot: [2,5] [==================--------------------------------------------------------] 24% est: 8s 
 plot: [2,6] [====================------------------------------------------------------] 27% est: 8s 
 plot: [2,7] [=====================-----------------------------------------------------] 29% est: 8s 
 plot: [3,1] [=======================---------------------------------------------------] 31% est: 7s 
 plot: [3,2] [========================--------------------------------------------------] 33% est: 7s 
 plot: [3,3] [==========================------------------------------------------------] 35% est: 7s 
 plot: [3,4] [===========================-----------------------------------------------] 37% est: 7s 
 plot: [3,5] [=============================---------------------------------------------] 39% est: 6s 
 plot: [3,6] [==============================--------------------------------------------] 41% est: 6s 
 plot: [3,7] [================================------------------------------------------] 43% est: 6s 
 plot: [4,1] [=================================-----------------------------------------] 45% est: 6s 
 plot: [4,2] [===================================---------------------------------------] 47% est: 5s 
 plot: [4,3] [====================================--------------------------------------] 49% est: 5s 
 plot: [4,4] [======================================------------------------------------] 51% est: 5s 
 plot: [4,5] [=======================================-----------------------------------] 53% est: 5s 
 plot: [4,6] [=========================================---------------------------------] 55% est: 4s 
 plot: [4,7] [==========================================--------------------------------] 57% est: 4s 
 plot: [5,1] [============================================------------------------------] 59% est: 4s 
 plot: [5,2] [=============================================-----------------------------] 61% est: 4s 
 plot: [5,3] [===============================================---------------------------] 63% est: 4s 
 plot: [5,4] [================================================--------------------------] 65% est: 3s 
 plot: [5,5] [==================================================------------------------] 67% est: 3s 
 plot: [5,6] [===================================================-----------------------] 69% est: 3s 
 plot: [5,7] [=====================================================---------------------] 71% est: 3s 
 plot: [6,1] [======================================================--------------------] 73% est: 3s 
 plot: [6,2] [========================================================------------------] 76% est: 2s 
 plot: [6,3] [=========================================================-----------------] 78% est: 2s 
 plot: [6,4] [===========================================================---------------] 80% est: 2s 
 plot: [6,5] [============================================================--------------] 82% est: 2s 
 plot: [6,6] [==============================================================------------] 84% est: 2s 
 plot: [6,7] [===============================================================-----------] 86% est: 1s 
 plot: [7,1] [=================================================================---------] 88% est: 1s 
 plot: [7,2] [==================================================================--------] 90% est: 1s 
 plot: [7,3] [====================================================================------] 92% est: 1s 
 plot: [7,4] [=====================================================================-----] 94% est: 1s 
 plot: [7,5] [=======================================================================---] 96% est: 0s 
 plot: [7,6] [========================================================================--] 98% est: 0s 
 plot: [7,7] [==========================================================================]100% est: 0s 
                                                                                                      

Eye Gaze Data

Now eye gaze data. Boxplots first. Also here, we’re renaming “chin” to “neck” because that’s what it actually is! But we also have to fix all NA’s in the percentages to zeros, becuase that’s what they actually are.

# rename chin to neck
fulldata <- fulldata %>%
  rename(neck = chin) %>%
  gather(aoi, percent, belly:upperchest)
# Fix all NA's in Percent column to 0
fixpercent <- fulldata$percent
fulldata$percent <- coalesce(fixpercent, 0)
fulldata <- fulldata %>%
  spread(aoi, percent)
fulldata %>%
  filter(eye_exclude == FALSE) %>%
  select(direction, belly:upperchest) %>%
  gather(aoi, percent, belly:upperchest) %>%
  ggplot(aes(x = aoi, y = percent, fill = direction)) + geom_boxplot()

Forehead

This is going to get complicated - we need to run all 6 ANOVAs/ANCOVAs on 5 AOIs. That’s 30 models. Thank goodness for find-and-replace! I’m going to skip the LSD comparisons for now, to make it easier to just scroll through.

  1. ANOVA with factors MainGroup & Direction.
                    Df  Sum Sq  Mean Sq F value Pr(>F)  
maingroup            3 0.00957 0.003191   2.309 0.0814 .
direction            1 0.00304 0.003044   2.202 0.1411  
maingroup:direction  3 0.00382 0.001273   0.921 0.4340  
Residuals           95 0.13132 0.001382                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df   Sum Sq   Mean Sq F value Pr(>F)
maingroup    3 0.001415 0.0004717   1.782  0.163
Residuals   48 0.012704 0.0002647               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df  Sum Sq  Mean Sq F value Pr(>F)
maingroup    3 0.01193 0.003977   1.576  0.208
Residuals   47 0.11862 0.002524               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df  Sum Sq   Mean Sq F value Pr(>F)
direction            1 0.00309 0.0030909   2.045  0.156
aoasl                1 0.00009 0.0000867   0.057  0.811
age                  1 0.00032 0.0003163   0.209  0.648
direction:aoasl      1 0.00016 0.0001580   0.105  0.747
direction:age        1 0.00022 0.0002163   0.143  0.706
aoasl:age            1 0.00009 0.0000923   0.061  0.805
direction:aoasl:age  1 0.00018 0.0001784   0.118  0.732
Residuals           95 0.14362 0.0015118               
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = forehead ~ aoasl * age, data = filter(aoi5_data, 
    direction == "forward"))

Residuals:
      Min        1Q    Median        3Q       Max 
-0.010785 -0.008783 -0.005130 -0.003979  0.061707 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  3.797e-03  1.685e-02   0.225    0.823
aoasl        4.507e-04  1.207e-03   0.373    0.710
age          2.391e-05  4.882e-04   0.049    0.961
aoasl:age   -5.838e-06  3.740e-05  -0.156    0.877

Residual standard error: 0.017 on 48 degrees of freedom
Multiple R-squared:  0.01786,   Adjusted R-squared:  -0.04352 
F-statistic: 0.291 on 3 and 48 DF,  p-value: 0.8317
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = forehead ~ aoasl * age, data = filter(aoi5_data, 
    direction == "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.02793 -0.01961 -0.01649 -0.01334  0.23359 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  4.482e-02  5.210e-02   0.860    0.394
aoasl       -1.290e-03  3.731e-03  -0.346    0.731
age         -7.676e-04  1.511e-03  -0.508    0.614
aoasl:age    3.574e-05  1.156e-04   0.309    0.759

Residual standard error: 0.05254 on 47 degrees of freedom
Multiple R-squared:  0.006095,  Adjusted R-squared:  -0.05735 
F-statistic: 0.09608 on 3 and 47 DF,  p-value: 0.9618

Eyes

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value Pr(>F)
maingroup            3  0.315 0.10508   1.936  0.129
direction            1  0.000 0.00000   0.000  0.999
maingroup:direction  3  0.013 0.00425   0.078  0.972
Residuals           95  5.157 0.05429               
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.1234 0.04114   0.863  0.467
Residuals   48 2.2876 0.04766               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.2046 0.06820   1.117  0.352
Residuals   47 2.8695 0.06105               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value Pr(>F)
direction            1  0.000 0.00000   0.000  0.995
aoasl                1  0.047 0.04669   0.821  0.367
age                  1  0.009 0.00903   0.159  0.691
direction:aoasl      1  0.000 0.00008   0.001  0.971
direction:age        1  0.014 0.01362   0.239  0.626
aoasl:age            1  0.003 0.00258   0.045  0.832
direction:aoasl:age  1  0.007 0.00717   0.126  0.723
Residuals           95  5.406 0.05690               
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = eyes ~ aoasl * age, data = filter(aoi5_data, direction == 
    "forward"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.23543 -0.16625 -0.09484  0.13048  0.60413 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  0.1114653  0.2205845   0.505    0.616
aoasl        0.0093545  0.0157958   0.592    0.556
age          0.0019633  0.0063910   0.307    0.760
aoasl:age   -0.0002108  0.0004897  -0.431    0.669

Residual standard error: 0.2225 on 48 degrees of freedom
Multiple R-squared:  0.01437,   Adjusted R-squared:  -0.04723 
F-statistic: 0.2333 on 3 and 48 DF,  p-value: 0.8727
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = eyes ~ aoasl * age, data = filter(aoi5_data, direction == 
    "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.25646 -0.18517 -0.08579  0.17714  0.62517 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.095e-01  2.517e-01   0.435    0.666
aoasl       1.935e-03  1.803e-02   0.107    0.915
age         2.005e-03  7.300e-03   0.275    0.785
aoasl:age   5.266e-05  5.588e-04   0.094    0.925

Residual standard error: 0.2539 on 47 degrees of freedom
Multiple R-squared:  0.01448,   Adjusted R-squared:  -0.04843 
F-statistic: 0.2302 on 3 and 47 DF,  p-value: 0.8749

Mouth

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value Pr(>F)  
maingroup            3  0.499 0.16623   2.533 0.0616 .
direction            1  0.246 0.24582   3.745 0.0559 .
maingroup:direction  3  0.029 0.00955   0.146 0.9323  
Residuals           95  6.235 0.06563                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.1506 0.05021   0.909  0.444
Residuals   48 2.6511 0.05523               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3  0.368 0.12263   1.608    0.2
Residuals   47  3.584 0.07625               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value  Pr(>F)   
direction            1  0.255  0.2546   3.875 0.05191 . 
aoasl                1  0.037  0.0368   0.561 0.45580   
age                  1  0.459  0.4593   6.991 0.00958 **
direction:aoasl      1  0.003  0.0027   0.041 0.84063   
direction:age        1  0.009  0.0089   0.136 0.71335   
aoasl:age            1  0.001  0.0011   0.017 0.89558   
direction:aoasl:age  1  0.003  0.0030   0.046 0.83099   
Residuals           95  6.242  0.0657                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = mouth ~ aoasl * age, data = filter(aoi5_data, direction == 
    "forward"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.44000 -0.20113  0.06621  0.19821  0.31155 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  0.3649728  0.2314635   1.577    0.121
aoasl        0.0049408  0.0165748   0.298    0.767
age          0.0084860  0.0067063   1.265    0.212
aoasl:age   -0.0001379  0.0005138  -0.268    0.790

Residual standard error: 0.2335 on 48 degrees of freedom
Multiple R-squared:  0.06612,   Adjusted R-squared:  0.007748 
F-statistic: 1.133 on 3 and 48 DF,  p-value: 0.3453
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = mouth ~ aoasl * age, data = filter(aoi5_data, direction == 
    "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.57201 -0.20495  0.01672  0.20824  0.37940 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  2.625e-01  2.754e-01   0.953    0.345
aoasl       -8.955e-04  1.972e-02  -0.045    0.964
age          8.966e-03  7.986e-03   1.123    0.267
aoasl:age    3.289e-05  6.112e-04   0.054    0.957

Residual standard error: 0.2777 on 47 degrees of freedom
Multiple R-squared:  0.08266,   Adjusted R-squared:  0.02411 
F-statistic: 1.412 on 3 and 47 DF,  p-value: 0.2511

Neck

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value Pr(>F)
maingroup            3  0.195 0.06505   1.584  0.198
direction            1  0.095 0.09484   2.309  0.132
maingroup:direction  3  0.040 0.01326   0.323  0.809
Residuals           95  3.902 0.04107               
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.0557 0.01857   0.583  0.629
Residuals   48 1.5296 0.03187               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.1758 0.05860   1.161  0.335
Residuals   47 2.3723 0.05048               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value  Pr(>F)   
direction            1  0.098 0.09830   2.499 0.11721   
aoasl                1  0.048 0.04800   1.220 0.27206   
age                  1  0.282 0.28158   7.160 0.00878 **
direction:aoasl      1  0.000 0.00005   0.001 0.97094   
direction:age        1  0.024 0.02403   0.611 0.43638   
aoasl:age            1  0.034 0.03404   0.866 0.35455   
direction:aoasl:age  1  0.010 0.00971   0.247 0.62033   
Residuals           95  3.736 0.03933                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = neck ~ aoasl * age, data = filter(aoi5_data, direction == 
    "forward"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.21315 -0.09850 -0.05872  0.03555  0.59574 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept)  0.4618934  0.1722346   2.682   0.0100 *
aoasl       -0.0181887  0.0123335  -1.475   0.1468  
age         -0.0091690  0.0049902  -1.837   0.0723 .
aoasl:age    0.0004405  0.0003823   1.152   0.2550  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1737 on 48 degrees of freedom
Multiple R-squared:  0.08614,   Adjusted R-squared:  0.02902 
F-statistic: 1.508 on 3 and 48 DF,  p-value: 0.2244
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = neck ~ aoasl * age, data = filter(aoi5_data, direction == 
    "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.26322 -0.14892 -0.05726  0.06747  0.61028 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept)  0.5422914  0.2187298   2.479   0.0168 *
aoasl       -0.0097882  0.0156634  -0.625   0.5351  
age         -0.0096767  0.0063433  -1.525   0.1338  
aoasl:age    0.0001337  0.0004855   0.275   0.7842  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2206 on 47 degrees of freedom
Multiple R-squared:  0.1024,    Adjusted R-squared:  0.04508 
F-statistic: 1.787 on 3 and 47 DF,  p-value: 0.1626

Upperchest

  1. ANOVA with factors MainGroup & Direction.
                    Df  Sum Sq  Mean Sq F value  Pr(>F)   
maingroup            3 0.02930 0.009767   5.796 0.00111 **
direction            1 0.00191 0.001909   1.133 0.28987   
maingroup:direction  3 0.00304 0.001013   0.601 0.61589   
Residuals           95 0.16009 0.001685                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df  Sum Sq  Mean Sq F value Pr(>F)
maingroup    3 0.00916 0.003053   1.958  0.133
Residuals   48 0.07484 0.001559               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df  Sum Sq  Mean Sq F value  Pr(>F)   
maingroup    3 0.02309 0.007695   4.243 0.00984 **
Residuals   47 0.08525 0.001814                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df  Sum Sq  Mean Sq F value  Pr(>F)   
direction            1 0.00200 0.002004   1.173 0.28147   
aoasl                1 0.00634 0.006342   3.713 0.05698 . 
age                  1 0.01797 0.017971  10.522 0.00163 **
direction:aoasl      1 0.00124 0.001239   0.725 0.39652   
direction:age        1 0.00016 0.000158   0.092 0.76175   
aoasl:age            1 0.00301 0.003010   1.762 0.18755   
direction:aoasl:age  1 0.00135 0.001355   0.793 0.37537   
Residuals           95 0.16226 0.001708                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = upperchest ~ aoasl * age, data = filter(aoi5_data, 
    direction == "forward"))

Residuals:
      Min        1Q    Median        3Q       Max 
-0.034569 -0.019989 -0.008841  0.003154  0.191098 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  5.093e-02  3.929e-02   1.296    0.201
aoasl        9.317e-04  2.814e-03   0.331    0.742
age         -1.170e-03  1.138e-03  -1.028    0.309
aoasl:age   -2.810e-05  8.722e-05  -0.322    0.749

Residual standard error: 0.03963 on 48 degrees of freedom
Multiple R-squared:  0.1024,    Adjusted R-squared:  0.04628 
F-statistic: 1.825 on 3 and 48 DF,  p-value: 0.1552
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = upperchest ~ aoasl * age, data = filter(aoi5_data, 
    direction == "reversed"))

Residuals:
      Min        1Q    Median        3Q       Max 
-0.058713 -0.020916 -0.006297  0.003274  0.170664 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept)  2.021e-02  4.262e-02   0.474   0.6377  
aoasl        5.292e-03  3.052e-03   1.734   0.0895 .
age         -2.694e-04  1.236e-03  -0.218   0.8285  
aoasl:age   -1.427e-04  9.461e-05  -1.508   0.1383  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.04299 on 47 degrees of freedom
Multiple R-squared:  0.1982,    Adjusted R-squared:  0.147 
F-statistic: 3.873 on 3 and 47 DF,  p-value: 0.01483

FaceChest

We originally defined FaceChest such that

  1. Face = eyes + mouth + chin
  2. Chest = upperchest + midchest + lowerchest

BUT. Chin is actually neck. It’s not even part of the face if you think about it. So I’m redefining FaceChest as:

  1. Face = forehead + eyes + mouth
  2. Chest = neck + upperchest + midchest + lowerchest

So let’s do this. Then see what’s happening across groups for FaceChest.

Cool. Next we’ll do error bar charts using the new FaceChest across groups.

facechest_info <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  group_by(maingroup, direction, participant) %>%
  summarise(facechest = mean(facechest, na.rm = TRUE)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(facechest),
            sd = sd(facechest),
            n = n(),
            se = sd/sqrt(n))
ggplot(facechest_info, aes(x = maingroup, y = mean, fill = direction, color = direction)) +
  geom_point(stat = "identity", position = position_dodge(0.5), size = 2) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.5), width = 0.3, size = 1) +
  labs(title = "FaceChest Ratio", subtitle = "Error bars represent SE", x = "", y = "facechest ratio") +
  scale_y_continuous(limits = c(-1,1)) + 
  geom_hline(yintercept = 0, linetype = "dotted")

Now let’s do the ANOVAs. Also skipping LSDs here.

  1. ANOVA with factors MainGroup & Direction.
Grouping rowwise data frame strips rowwise nature
                    Df Sum Sq Mean Sq F value Pr(>F)  
maingroup            3  1.317  0.4389   2.111 0.1040  
direction            1  0.712  0.7116   3.422 0.0674 .
maingroup:direction  3  0.283  0.0942   0.453 0.7157  
Residuals           95 19.754  0.2079                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3  0.295 0.09847   0.608  0.613
Residuals   48  7.777 0.16202               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3  1.279  0.4264   1.673  0.185
Residuals   47 11.977  0.2548               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value  Pr(>F)   
direction            1  0.736  0.7363   3.722 0.05667 . 
aoasl                1  0.014  0.0140   0.071 0.79077   
age                  1  2.218  2.2182  11.215 0.00116 **
direction:aoasl      1  0.024  0.0245   0.124 0.72574   
direction:age        1  0.162  0.1617   0.818 0.36814   
aoasl:age            1  0.026  0.0256   0.130 0.71972   
direction:aoasl:age  1  0.093  0.0934   0.472 0.49369   
Residuals           95 18.791  0.1978                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = facechest ~ aoasl * age, data = filter(fc_data, 
    direction == "forward"))

Residuals:
    Min      1Q  Median      3Q     Max 
-1.1587 -0.1404  0.1393  0.2517  0.4754 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept) -0.0308724  0.3874355  -0.080   0.9368  
aoasl        0.0306476  0.0277438   1.105   0.2748  
age          0.0207509  0.0112253   1.849   0.0707 .
aoasl:age   -0.0007246  0.0008600  -0.843   0.4037  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3908 on 48 degrees of freedom
Multiple R-squared:  0.09183,   Adjusted R-squared:  0.03507 
F-statistic: 1.618 on 3 and 48 DF,  p-value: 0.1975
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = facechest ~ aoasl * age, data = filter(fc_data, 
    direction == "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-1.19830 -0.16427  0.08831  0.31808  0.62208 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.1552602  0.4895982  -0.317    0.753
aoasl        0.0004786  0.0350606   0.014    0.989
age          0.0204410  0.0141987   1.440    0.157
aoasl:age    0.0002265  0.0010868   0.208    0.836

Residual standard error: 0.4938 on 47 degrees of freedom
Multiple R-squared:  0.1355,    Adjusted R-squared:  0.08032 
F-statistic: 2.456 on 3 and 47 DF,  p-value: 0.07467

MouthEye

We’ve also got a moutheye ratio! Maybe something there, too.

moutheye_info <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  group_by(maingroup, direction, participant) %>%
  summarise(moutheye = mean(moutheye, na.rm = TRUE)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(moutheye, na.rm = TRUE),
            sd = sd(moutheye, na.rm = TRUE),
            n = n(),
            se = sd/sqrt(n))
ggplot(moutheye_info, aes(x = maingroup, y = mean, fill = direction, color = direction)) +
  geom_point(stat = "identity", position = position_dodge(0.5), size = 2) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.5), width = 0.3, size = 1) +
  labs(title = "MouthEye Ratio", subtitle = "Error bars represent SE", x = "", y = "moutheye ratio") +
  scale_y_continuous(limits = c(-1,1)) + 
  geom_hline(yintercept = 0, linetype = "dotted")

And Moutheye ANOVAs. Also skipping LSDs here.

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value Pr(>F)  
maingroup            3  2.077  0.6923   2.538 0.0612 .
direction            1  0.061  0.0612   0.225 0.6367  
maingroup:direction  3  0.104  0.0347   0.127 0.9437  
Residuals           95 25.912  0.2728                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3  0.712  0.2374   1.086  0.364
Residuals   48 10.494  0.2186               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3  1.466  0.4887    1.49  0.229
Residuals   47 15.419  0.3281               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value Pr(>F)
direction            1  0.064 0.06376   0.219  0.641
aoasl                1  0.302 0.30238   1.036  0.311
age                  1  0.002 0.00225   0.008  0.930
direction:aoasl      1  0.000 0.00005   0.000  0.990
direction:age        1  0.025 0.02513   0.086  0.770
aoasl:age            1  0.022 0.02165   0.074  0.786
direction:aoasl:age  1  0.023 0.02262   0.078  0.781
Residuals           95 27.717 0.29175               
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = moutheye ~ aoasl * age, data = filter(fc_data, direction == 
    "forward"))

Residuals:
    Min      1Q  Median      3Q     Max 
-1.1953 -0.2816  0.2015  0.3433  0.5118 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)
(Intercept)  0.740418   0.474760   1.560    0.125
aoasl       -0.020911   0.033997  -0.615    0.541
age         -0.003540   0.013755  -0.257    0.798
aoasl:age    0.000463   0.001054   0.439    0.662

Residual standard error: 0.4789 on 48 degrees of freedom
Multiple R-squared:  0.01766,   Adjusted R-squared:  -0.04374 
F-statistic: 0.2877 on 3 and 48 DF,  p-value: 0.8341
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = moutheye ~ aoasl * age, data = filter(fc_data, direction == 
    "reversed"))

Residuals:
    Min      1Q  Median      3Q     Max 
-1.4288 -0.2857  0.2498  0.4508  0.5968 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  6.610e-01  5.912e-01   1.118    0.269
aoasl       -7.896e-03  4.233e-02  -0.187    0.853
age         -2.437e-03  1.714e-02  -0.142    0.888
aoasl:age   -5.108e-06  1.312e-03  -0.004    0.997

Residual standard error: 0.5962 on 47 degrees of freedom
Multiple R-squared:  0.01043,   Adjusted R-squared:  -0.05273 
F-statistic: 0.1652 on 3 and 47 DF,  p-value: 0.9193

Heat Maps

And finally, we’re going to do heat maps.

eyegaze_heat <- fulldata %>%
  ungroup() %>%
  filter(eye_exclude == FALSE) %>%
  select(id:direction, belly, lowerchest, midchest, upperchest, neck, mouth, eyes, forehead) %>%
  gather(aoi, percent, belly:forehead) %>%
  group_by(maingroup, participant, direction, aoi) %>%
  summarise(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,direction,aoi) %>%
  summarise(percent = mean(percent, na.rm=TRUE)) %>%
  ungroup() %>%
  filter(!is.na(aoi)) %>%
  mutate(aoi = factor(aoi,levels=c("belly","lowerchest","midchest",
                                   "upperchest","neck","mouth","eyes","forehead")))
eyegaze_heat_all <- fulldata %>%
  ungroup() %>%
  filter(eye_exclude == FALSE) %>%
  select(id:direction, belly, lowerchest, midchest, upperchest, neck, mouth, eyes, forehead) %>%
  gather(aoi, percent, belly:forehead) %>%
  group_by(maingroup,participant,direction,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,direction,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  ungroup() %>%
  filter(!is.na(aoi)) %>%
  mutate(aoi = factor(aoi,levels=c("belly","lowerchest","midchest",
                                   "upperchest","neck","mouth","eyes","forehead")))
ggplot(eyegaze_heat, aes(x = maingroup, y = aoi)) +
  geom_tile(aes(fill=percent),color="lightgray",na.rm=TRUE) + 
#  scale_fill_gradient(low = "lightblue",high = "steelblue") +
#  scale_fill_distiller(type="div", palette = "RdYlBu") +
  scale_fill_viridis(option = "viridis", direction=-1, limits = c(0,.75)) +
  theme(axis.text.x=element_text(angle=45,hjust=1)) + facet_grid(. ~ direction) +
  ylab("") + xlab("") + ggtitle("Eye Gaze Heat Map, by Direction")

ggplot(eyegaze_heat_all, aes(x = maingroup, y = aoi)) +
  geom_tile(aes(fill=percent),color="lightgray",na.rm=TRUE) + 
#  scale_fill_gradient(low = "lightblue",high = "steelblue") +
#  scale_fill_distiller(type="div", palette = "RdYlBu") +
  scale_fill_viridis(option = "viridis", direction=-1, limits = c(0,.75)) +
  theme(axis.text.x=element_text(angle=45,hjust=1)) +
  ylab("") + xlab("") + ggtitle("Eye Gaze Heat Map (Direction Collapsed)")

Summary

Below are the p-values from the ANOVAs with 4 MainGroups. I never included Age as a covariate because it never improved the model. I included all ANOVAs for Gist and Lex Recall, and ANOVAs for any eye AOI or ratio was included only if either maingroup or direction was significant. Deafearly-Deaflate shows the LSD p-value for that comparison.

results1 <- structure(list(model = c("gist-maingroup-both", "gist-maingroup-fw", 
"gist-maingroup-rv", "lexrecall-maingroup-both", "lexrecall-maingroup-fw", 
"lexrecall-maingroup-rv", "mouth-maingroup-both", "upperchest-maingroup-both", 
"upperchest-maingroup-rv", "facechest-maingroup-both", "moutheye-maingroup-both"
), maingroup = c(0, 0, 0.01, 0, 0.04, 0.02, 0.06, 0, 0.01, 0.1, 
0.05), direction = c(0, NA, NA, 0, NA, NA, 0.06, 0.16, NA, 0.07, 
0.48), `deafearly-deaflate` = c(0.1, 0.69, 0.02, 0.11, 0.95, 
0.06, 0.38, 0.94, 0.52, 0.08, 0.68)), .Names = c("model", "maingroup", 
"direction", "deafearly-deaflate"), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -11L))
results1

And below are the p-values from the ANCOVAs with Hearing & AoASL. I included all ANCOVAs for Gist and Lex Recall, and ANCOVAs for any eye AOI or ratio was included only if any main factor was significant. LSD comparisons are not needed because there’s only 2 levels in each group!

results2 <- structure(list(model = c("gist-both", "gist-fw", "gist-rv", "lex-both", 
"lex-fw", "lex-rv", "forehead-fw", "mouth-both", "mouth-rv", 
"upperchest-both", "upperchest-rv", "facechest-both", "moutheye-both"
), hearing = c(0, 0.00, 0.01, 0.01, 0.22, 0.03, 0.06, 0.01, 
0.04, 0.01, 0.01, 0.35, 0.07), direction = c(0, NA, NA, 0, NA, 
NA, NA, 0.05, NA, 0.21, NA, 0.05, 0.52), aoasl = c(0.22, 0.77, 
0.19, 0.56, 0.58, 0.25, 0.08, 0.06, 0.12, 0.68, 0.95, 0.12, 0.44
), age = c(0.08, 0.01, 0.86, 0.09, 0.02, 0.7, 0.68, 0.28, 0.5, 
0.02, 0.08, 0.00, 0.21)), .Names = c("model", "hearing", "direction", 
"aoasl", "age"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-13L))
results2

Finally, the correlations for Deaf and Hearing separately are not significant. But there are significant correlations across all participants. I worry it is caused by HearingNovice, though…

results3 <- tribble(
  ~ metric, ~ AoASLcorrelationRvalue, ~ Pvalue,
  "gist-fw", -0.32, 0.019,
  "gist-rv", -0.39, 0.004,
  "lex-fw", -0.08, 0.567,
  "lex-rv", -0.34, 0.014
)
results3

Rain’s Notes

About Adults:

-I think I want to write it up as an ANCOVA, with direction included. And LSD comparisons instead of Tukey. (I will do my own corrections) -You often have one liners summarizing results, in all tabs, those are nice, keep them coming. -(If you have reasons to present anything other than the ANCOVA, put that in your results tab)

I think if we do it this way then we get a really important story to tell: That the critical AoA cutoff is below 4 vs above 4 years of age (two groups 0-4 vs 4-13). This suggest early ASL is important.

Ternary Plots

Let’s make triangle plots. “What?” you say. Read on.

library(ggtern)
fulldata %>% 
  ggtern(aes(x = eyes, y = mouth, z = neck)) + facet_grid(direction ~ maingroup) + stat_density_tern(geom='polygon', aes(fill=..level..), bins=4) + geom_point(color = "white", alpha = 0.5) + theme_bw()

fulldata %>% 
  ggtern(aes(x = eyes, y = mouth, z = neck)) + facet_grid(direction ~ maingroup) + geom_confidence_tern(breaks = c(.5), color = "red") + geom_point() + theme_bw()

LS0tCnRpdGxlOiAiVGhlIExhc3QgRGF0YSBBbmFseXNpcyB0byBSdWxlIFRoZW0gQWxsPyAoc3R1ZHkxYWR1bHRzKSIKYXV0aG9yOiAiQWRhbSBTdG9uZSwgUGhEIiAKZGF0ZTogJ2ByIGZvcm1hdChTeXMuRGF0ZSgpLCAiJW0tJWQtJVkiKWAnCm91dHB1dDoKICBnaXRodWJfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAyCiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdGhlbWU6IHBhcGVyCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAyCiAgICB0b2NfZmxvYXQ6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKIyBQdXR0aW5nIEl0IEFsbCBCYWNrIFRvZ2V0aGVyCgpUaHJvdWdob3V0IGFsbCB0aGUgZGF0YSBhbmFseXNpcyB3ZSd2ZSBkb25lLCB0aGUgZGF0YXNldHMgaGF2ZSBiZWNvbWUgbW9yZSBmcmFnbWVudGVkIC0gbGV4aWNhbCByZWNhbGwsIGdpc3QsIGFuZCBleWUgdHJhY2tpbmcgZGF0YXNldHMuIEkgd2FudCB0byBwdXQgdGhlbSBhbGwgdG9nZXRoZXIgaW4gb25lIHdob2xlIGRhdGFzZXQgYWdhaW4gc28gd2UgY2FuIHBlcmZvcm0gc29tZSBhbmFseXNlcyBtb3JlIGVmZmljaWVudGx5IChwYXJ0aWN1bGFybHkgY29ycmVsYXRpb25zKS4gVGhlIG9ubHkgdGhpbmcgSSBuZWVkIHRvIHJlbWVtYmVyIGlzIHdlJ2xsIGhhdmUgYSBuZXcgY29sdW1uIGNhbGxlZCBgZXllX2V4Y2x1ZGVgIGFuZCBpZiBpdCBpcyBzZXQgdG8gYFRSVUVgIGl0IG1lYW5zIHdlIGNhbid0IGluY2x1ZGUgdGhhdCByb3cgaW4gYW55IGFuYWx5c2lzIHJlbGF0aW5nIHRvIGV5ZSBnYXplICh1c3VhbGx5IGJlY2F1c2UgdGhhdCB0cmlhbCB3YXMgbGVzcyB0aGFuIDI1JSBsb29raW5nKS4gCgpgYGB7ciBzbWFzaCBkYXRhIHRvZ2V0aGVyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIExpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsbWU0KQpsaWJyYXJ5KGxtZXJUZXN0KQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGFncmljb2xhZSkgCmxpYnJhcnkoR0dhbGx5KQoKIyBMb2FkIGxleCBhbmQgZXllIGRhdGEKY2xlYW5sZXhkYXRhIDwtIHJlYWRfY3N2KCJjbGVhbmRhdGEuY3N2IikgJT4lCiAgc2VsZWN0KC0oZm9yZWhlYWQ6dG90YWwpKQoKY2xlYW5leWVkYXRhIDwtIHJlYWRfY3N2KCJjbGVhbnBlcmNlbnRkYXRhLmNzdiIpICU+JQogIHNwcmVhZChhb2kscGVyY2VudCkgJT4lCiAgYWRkX2NvbHVtbihleWVfZXhjbHVkZSA9IEZBTFNFKQoKIyBXaGF0IHJvd3Mgd2VyZSByZW1vdmVkIGZyb20gdGhlIGV5ZSBkYXRhIGJhY2sgaW4gMDNleWVnYXplPyBMZXQncyBhZGQgYmFjayBpbgojIFdpdGggYSBuZXcgY29sdW1uIC0gZXllX2V4Y2x1ZGUKcmVtb3ZlZCA8LSBhbnRpX2pvaW4oY2xlYW5sZXhkYXRhLCBjbGVhbmV5ZWRhdGEpICU+JQogIGFkZF9jb2x1bW4oZXllX2V4Y2x1ZGUgPSBUUlVFKQpleWVsZXhkYXRhIDwtIGJpbmRfcm93cyhjbGVhbmV5ZWRhdGEsIHJlbW92ZWQpCgojIExvYWQgZ2lzdCBkYXRhCmdpc3QgPC0gcmVhZF9jc3YoJ2dpc3RfaW5kaXYuY3N2JywgY29sX3R5cGVzID0gY29scygKICBwYXJ0aWNpcGFudCA9IGNvbF9jaGFyYWN0ZXIoKSwKICBnaXN0LmZ3MSA9IGNvbF9pbnRlZ2VyKCksCiAgZ2lzdC5ydjIgPSBjb2xfaW50ZWdlcigpLAogIGdpc3QuZnczID0gY29sX2ludGVnZXIoKSwKICBnaXN0LnJ2NCA9IGNvbF9pbnRlZ2VyKCkKKSkgJT4lCiAgZ2F0aGVyKHZpZGVvLCBnaXN0LCBnaXN0LmZ3MTpnaXN0LnJ2NCkgJT4lCiAgbXV0YXRlKHZpZGVvID0gc3RyX3N1Yih2aWRlbyw2LDgpKQoKIyBQcmVzdG8sIG91ciBmdWxsIHJldW5pZmllZCBkYXRhc2V0IC0gJ2Z1bGxkYXRhJwojIEJ1dCBJIHdhbnQgdG8gcmVtb3ZlIGNvbHVtbnMgSSBkb24ndCB3YW50IGFueW1vcmUKZnVsbGRhdGEgPC0gbGVmdF9qb2luKGV5ZWxleGRhdGEsIGdpc3QpICU+JQogIHNlbGVjdCgtbW91dGhleWUsIC1mYWNlY2hlc3QsIC1mYWNlLCAtY2hlc3QpCmBgYAoKIyBHcm91cCBDaGFuZ2VzIGFuZCBQYXJ0aWNpcGFudCBUYWJsZXMKCldlIGhhdmUgc29tZSBjaGFuZ2VzIHRvIG1ha2UgdG8gdGhlIGdyb3Vwcy4gRmlyc3QsIGZpeCBKb3NoIGFzIGxlYXJuaW5nIEFTTCB3aGVuIGhlIHdhcyA2LiBOZXh0LCBkcm9wIHRoZSBEZWFmTmF0aXZlIEdyb3VwIGFuZCByZWNsYXNzaWZ5IGFsbCB3aG8gbGVhcm5lZCBBU0wgPCAzLjkgYXMgRGVhZkVhcmx5IGFuZCBBU0wgPT4gNC4wIGFzIERlYWZMYXRlLiAKCmBgYHtyIGdyb3VwcyBhbmQgcGFydGljaXBhbnQgdGFibGVzfQojIENoYW5nZSBKb3NoJ3MgQW9BU0wgdG8gNgpmdWxsZGF0YSA8LSBmdWxsZGF0YSAlPiUKICBtdXRhdGUoYW9hc2wgPSBhcy5kb3VibGUoYW9hc2wpKSAlPiUKICBtdXRhdGUoYW9hc2wgPSBjYXNlX3doZW4oCiAgICBwYXJ0aWNpcGFudCA9PSAiSm9zaCIgfiA2LAogICAgVFJVRSB+IGFvYXNsCiAgKSkKCiMgUmVjbGFzc2lmeSBHcm91cHMKZnVsbGRhdGEgPC0gZnVsbGRhdGEgJT4lCiAgbXV0YXRlKG1haW5ncm91cCA9IGNhc2Vfd2hlbigKICAgIGhlYXJpbmcgPT0gIkRlYWYiICYgYW9hc2wgPCA0IH4gIkRlYWZFYXJseSIsCiAgICBoZWFyaW5nID09ICJEZWFmIiAmIGFvYXNsID49IDQgfiAiRGVhZkxhdGUiLAogICAgbWFpbmdyb3VwID09ICJIZWFyaW5nTGF0ZUFTTCIgfiAiSGVhcmluZ0xhdGUiLAogICAgbWFpbmdyb3VwID09ICJIZWFyaW5nTm92aWNlQVNMIiB+ICJIZWFyaW5nTm92aWNlIgogICkpCgojIENyZWF0ZSBQYXJ0aWNpcGFudCBEZW1vZ3JhcGhpY3MgVGFibGUKcGFydGljaXBhbnRfaW5mbyA8LSBmdWxsZGF0YSAlPiUKICBzZWxlY3QoLShhY2M6Z2lzdCkpICU+JQogIHNlbGVjdCgtKHZpZGVvOmRpcmVjdGlvbikpICU+JQogIGRpc3RpbmN0KCkgJT4lIAogIGdyb3VwX2J5KG1haW5ncm91cCkgJT4lCiAgc3VtbWFyaXNlKG4gPSBuKCksCiAgICAgICAgICAgIGFnZV9tZWFuID0gbWVhbihhZ2UpLAogICAgICAgICAgICBhZ2Vfc2QgPSBzZChhZ2UpLAogICAgICAgICAgICBhb2FzbF9tZWFuID0gbWVhbihhb2FzbCksCiAgICAgICAgICAgIGFvYXNsX3NkID0gc2QoYW9hc2wpLAogICAgICAgICAgICBzaWdueXJzX21lYW4gPSBtZWFuKHNpZ255cnMpLAogICAgICAgICAgICBzaWdueXJzX3NkID0gc2Qoc2lnbnlycyksCiAgICAgICAgICAgIHNlbGZyYXRlX21lYW4gPSBtZWFuKHNlbGZyYXRlKSwKICAgICAgICAgICAgc2VsZnJhdGVfc2QgPSBzZChzZWxmcmF0ZSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGVfaWYoaXMuZG91YmxlLCBmdW5zKHJvdW5kKC4sIDIpKSkgJT4lCiAgbXV0YXRlKGFnZSA9IHBhc3RlKGFnZV9tZWFuLCAiwrEiLCBhZ2Vfc2QsIHNlcCA9ICIgIiksCiAgICAgICAgIGFvYXNsID0gcGFzdGUoYW9hc2xfbWVhbiwgIsKxIiwgYW9hc2xfc2QsIHNlcCA9ICIgIiksCiAgICAgICAgIHNpZ255cnMgPSBwYXN0ZShzaWdueXJzX21lYW4sICLCsSIsIHNpZ255cnNfc2QsIHNlcCA9ICIgIiksCiAgICAgICAgIHNlbGZyYXRlID0gcGFzdGUoc2VsZnJhdGVfbWVhbiwgIsKxIiwgc2VsZnJhdGVfc2QsIHNlcCA9ICIgIikpICU+JQogIHNlbGVjdCgtKGFnZV9tZWFuOnNlbGZyYXRlX3NkKSkgJT4lCiAgcHJpbnQoKQpgYGAKIyMgUGFydGljaXBhbnQgQU5PVkFzIAoKQmVsb3cgYXJlIHRoZSBBTk9WQSBvdXRwdXRzIGZvciBwYXJ0aWNpcGFudCBkZW1vZ3JhcGhpY3MsIGFuZCBMU0RzIGZvciBlYWNoLiAKClBhcnRpY2lwYW50cycgYWdlCmBgYHtyIHN1YmplY3QgYW5vdmEgYWdlLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KIyBNYWtlIHRoZSBwYXJ0aWNpcGFudCBkYXRhIGZyYW1lCnBfYW5vdmFzIDwtIGZ1bGxkYXRhICU+JQogIHNlbGVjdCgtKGFjYzpnaXN0KSkgJT4lCiAgc2VsZWN0KC0odmlkZW86ZGlyZWN0aW9uKSkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBzZWxlY3QobWFpbmdyb3VwOmFvYXNsKQoKIyBBZ2UgQU5PVkEKcF9hZ2UgPC0gYW92KGFnZSB+IG1haW5ncm91cCwgZGF0YSA9IHBfYW5vdmFzKQpzdW1tYXJ5KHBfYWdlKQpMU0QudGVzdChwX2FnZSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpJGNvbXBhcmlzb24KYGBgCgoKUGFydGljaXBhbnRzJyBBb0FTTApgYGB7ciBzdWJqZWN0IGFub3ZhIGFvYXNsLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KIyBBb0FTTCBBTk9WQQpwX2FvYXNsIDwtIGFvdihhb2FzbCB+IG1haW5ncm91cCwgZGF0YSA9IHBfYW5vdmFzKQpzdW1tYXJ5KHBfYW9hc2wpCkxTRC50ZXN0KHBfYW9hc2wsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKSRjb21wYXJpc29uCmBgYAoKUGFydGljaXBhbnRzJyBTaWduIFlycwpgYGB7ciBzdWJqZWN0IGFub3ZhIHNpZ255cnMsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFfQojIFNpZ255cnMgQU5PVkEKcF9zaWdueXJzIDwtIGFvdihzaWdueXJzIH4gbWFpbmdyb3VwLCBkYXRhID0gcF9hbm92YXMpCnN1bW1hcnkocF9zaWdueXJzKQpMU0QudGVzdChwX3NpZ255cnMsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKSRjb21wYXJpc29uCmBgYAoKUGFydGljaXBhbnRzJyBTZWxmLVJhdGluZwpgYGB7ciBzdWJqZWN0IGFub3ZhIHNlbGZyYXRlLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KIyBTZWxmcmF0ZSBBTk9WQQpwX3NlbGZyYXRlIDwtIGFvdihzZWxmcmF0ZSB+IG1haW5ncm91cCwgZGF0YSA9IHBfYW5vdmFzKQpzdW1tYXJ5KHBfc2VsZnJhdGUpCkxTRC50ZXN0KHBfc2VsZnJhdGUsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKSRjb21wYXJpc29uCmBgYAoKIyBHaXN0ICYgTGV4aWNhbCBSZWNhbGwgRGF0YQoKIyMgVGFibGVzICYgQ2hhcnRzCgpMZXQncyBnZW5lcmF0ZSBhIHRhYmxlIGZvciBsZXhpY2FsIHJlY2FsbCBhbmQgZ2lzdCBmb3IgZm9yd2FyZCB2cy4gcmV2ZXJzZWQgc3Rvcmllcy4gCgpgYGB7ciBsZXggJiBnaXN0IHRhYmxlfQpsZXhnaXN0X2luZm8gPC0gZnVsbGRhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShsZXhfbWVhbiA9IG1lYW4oYWNjLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBsZXhfc2QgPSBzZChhY2MsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGdpc3RfbWVhbiA9IG1lYW4oZ2lzdCksCiAgICAgICAgICAgIGdpc3Rfc2QgPSBzZChnaXN0KSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZV9pZihpcy5kb3VibGUsIGZ1bnMocm91bmQoLiwgMikpKSAlPiUgCiAgbXV0YXRlKGxleCA9IHBhc3RlKGxleF9tZWFuLCAiwrEiLCBsZXhfc2QsIHNlcCA9ICIgIiksCiAgICAgICAgIGdpc3QgPSBwYXN0ZShnaXN0X21lYW4sICLCsSIsIGdpc3Rfc2QsIHNlcCA9ICIgIikpICU+JQogIHNlbGVjdCgtKGxleF9tZWFuOmdpc3Rfc2QpKSAlPiUKICBnYXRoZXIobWV0cmljLCB2YWx1ZSwgbGV4Omdpc3QpICU+JQogIHVuaXRlKCJtZXRyaWMiLCBjKG1ldHJpYywgZGlyZWN0aW9uKSwgc2VwID0gIl8iKSAlPiUKICBzcHJlYWQobWV0cmljLCB2YWx1ZSkgJT4lCiAgcHJpbnQoKQpgYGAKCkFuZCB0aGVuIGJhciBjaGFydHMgdG9vIGFmdGVyIHRoYXQgd2l0aCBlcnJvciBiYXJzLiAKCmBgYHtyIGxleCBhbmQgZ2lzdCBiYXIgY2hhcnRzfQojIEdpc3QgYmFyIGNoYXJ0Cmdpc3RfYmFyIDwtIGZ1bGxkYXRhICU+JSBzZWxlY3QocGFydGljaXBhbnQsIG1haW5ncm91cCwgZGlyZWN0aW9uLCBnaXN0KSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShnaXN0ID0gbWVhbihnaXN0KSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihnaXN0KSwKICAgICAgICAgICAgc2QgPSBzZChnaXN0KSwKICAgICAgICAgICAgY291bnQgPSBuKCksCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChjb3VudCkpCgpnZ3Bsb3QoZ2lzdF9iYXIsIGFlcyh4ID0gbWFpbmdyb3VwLCB5ID0gbWVhbiwgZmlsbCA9IGRpcmVjdGlvbikpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuLXNlLCB5bWF4ID0gbWVhbitzZSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwgd2lkdGggPSAwLjUpICsKICBsYWJzKHRpdGxlID0gIlN0b3J5IENvbXByZWhlbnNpb24gKEdpc3QpIiwgc3VidGl0bGUgPSAiRXJyb3IgYmFycyByZXByZXNlbnQgU0UiLCB4ID0gIiIsIHkgPSAibWVhbiBnaXN0IikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50LCBsaW1pdHMgPSBjKDAsMSkpCgojIExleCBiYXIgY2hhcnQKbGV4X2JhciA8LSBmdWxsZGF0YSAlPiUgc2VsZWN0KHBhcnRpY2lwYW50LCBtYWluZ3JvdXAsIGRpcmVjdGlvbiwgYWNjKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShhY2MgPSBtZWFuKGFjYywgbmEucm0gPSBUUlVFKSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihhY2MsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIHNkID0gc2QoYWNjLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBjb3VudCA9IG4oKSwKICAgICAgICAgICAgc2UgPSBzZC9zcXJ0KGNvdW50KSkKCmdncGxvdChsZXhfYmFyLCBhZXMoeCA9IG1haW5ncm91cCwgeSA9IG1lYW4sIGZpbGwgPSBkaXJlY3Rpb24pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKyAKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbi1zZSwgeW1heCA9IG1lYW4rc2UpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHdpZHRoID0gMC41KSArCiAgbGFicyh0aXRsZSA9ICJMZXhpY2FsIFJlY2FsbCIsIHN1YnRpdGxlID0gIkVycm9yIGJhcnMgcmVwcmVzZW50IFNFIiwgeCA9ICIiLCB5ID0gIm1lYW4gYWNjdXJhY3kiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQsIGxpbWl0cyA9IGMoMCwxKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC41LCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC41LDEpKQpgYGAKCiMjIEFOT1ZBIFBsYW4KTmV4dCwgd2UncmUgZ29pbmcgdG8gZG8gQU5PVkFzIGFuZCBBTkNPVkFzLiBXZSdsbCBhbHdheXMgZG8gaXQgaW4gdGhpcyBvcmRlci4gVGhlIGZpcnN0IHRocmVlIEFOT1ZBcyB3aWxsIGJlIGZvbGxvd2VkIGJ5IExTRCBvZiB0aGUgZm91ciBtYWluZ3JvdXBzIHdpdGggKnVuY29ycmVjdGVkIHAtdmFsdWVzLiogCgoxLiBBTk9WQSB3aXRoIGZhY3RvcnMgTWFpbkdyb3VwICYgRGlyZWN0aW9uCjIuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIEZvcndhcmQgb25seQozLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBSZXZlcnNlIG9ubHkgCjQuIEFOQ09WQSB3aXRoIGZhY3RvciBEaXJlY3Rpb24sIGFuZCBjb3ZhcmlhdGUgQW9BU0wgYW5kIEFnZQo1LiBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFvQVNMIGFuZCBBZ2UsIGZvciBGb3J3YXJkIG9ubHkKNi4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBb0FTTCBhbmQgQWdlLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCkkgZGlkIG5vdCBpbmNsdWRlIEFnZSBhcyBhIGNvdmFyaWF0ZSBpbiB0aGUgZmlyc3QgMyBBTk9WQXMgYmVjYXVzZSB0aGV5IGRpZCBub3QgYWRkIHRvIG9yIGNoYW5nZSB0aGUgbW9kZWwgaW4gYW55IHNpZ25pZmljYW50IHdheS4gCgojIyBHaXN0IEFOT1ZBcwoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIGdpc3QgYW5vdmExLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgRmlyc3QgbGV0J3MgbWFrZSB0aGUgcGFydGljaXBhbnQtbGV2ZWwgZGF0YXNldCB3aXRoIHdoaWNoIHdlJ2xsIGRvIG91ciBBTkNPVkFzLiAKcGFydGljaXBhbnRfZGF0YSA8LSBmdWxsZGF0YSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBkaXJlY3Rpb24pICU+JQogIG11dGF0ZShnaXN0ID0gbWVhbihnaXN0LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICBhY2MgPSBtZWFuKGFjYywgbmEucm0gPSBUUlVFKSkgJT4lCiAgc2VsZWN0KGlkLCBwYXJ0aWNpcGFudCwgaGVhcmluZywgbWFpbmdyb3VwLCBkaXJlY3Rpb24sIGFnZSwgYW9hc2wsIGFjYywgZ2lzdCkgJT4lCiAgZGlzdGluY3QoKQoKIyBHaXN0IEFOT1ZBIDEKZ2lzdF9hb3YxIDwtIGFvdihnaXN0IH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gcGFydGljaXBhbnRfZGF0YSkKc3VtbWFyeShnaXN0X2FvdjEpCmdpc3RfbHNkMSA8LSBMU0QudGVzdChnaXN0X2FvdjEsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQpnaXN0X2xzZDEkY29tcGFyaXNvbgpgYGAKCjIuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIEZvcndhcmQgb25seS4gQWxzbyBhIEtydXNrYWwtV2FsbGlzIHRlc3QuIEFuZCBDaGktU3EgdG9vLiAKCmBgYHtyIGdpc3QgYW5vdmEyLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgR2lzdCBBTk9WQSAyCmdpc3RfYW92MiA8LSBhb3YoZ2lzdCB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShnaXN0X2FvdjIpCmdpc3RfbHNkMiA8LSBMU0QudGVzdChnaXN0X2FvdjIsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQpnaXN0X2xzZDIkY29tcGFyaXNvbgoKIyBLVyBOb24tcGFyYW1ldHJpYyB0ZXN0IChsaWtlIG9uZS13YXkgQU5PVkEpCmtydXNrYWwudGVzdChnaXN0IH4gbWFpbmdyb3VwLCBkYXRhID0gYXMubWF0cml4KGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkpCgojIENoaSBTcQpnaXN0X2NoaXNxX2Z3IDwtIHBhcnRpY2lwYW50X2RhdGEgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcihkaXJlY3Rpb24gPT0gImZvcndhcmQiKSAlPiUKICBzZWxlY3QobWFpbmdyb3VwLCBnaXN0KSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGdpc3QpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgc3ByZWFkKGdpc3QsIGNvdW50KSAlPiUKICByZW5hbWUobm9uZSA9ICIwIiwKICAgICAgICAgb25lID0gIjAuNSIsCiAgICAgICAgIGJvdGggPSAiMSIpCgpnaXN0X2NoaXNxX2Z3W2lzLm5hKGdpc3RfY2hpc3FfZncpXSA8LSAwTApnaXN0X2NoaXNxX2Z3IDwtIGNiaW5kKGdpc3RfY2hpc3FfZndbLCJub25lIl0sIGdpc3RfY2hpc3FfZndbLCJvbmUiXSwgZ2lzdF9jaGlzcV9md1ssImJvdGgiXSkKY2hpc3EudGVzdChnaXN0X2NoaXNxX2Z3KQpgYGAKCjMuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIFJldmVyc2Ugb25seS4gCgpgYGB7ciBnaXN0IGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIEdpc3QgQU5PVkEgMwpnaXN0X2FvdjMgPC0gYW92KGdpc3QgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIocGFydGljaXBhbnRfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KGdpc3RfYW92MykKZ2lzdF9sc2QzIDwtIExTRC50ZXN0KGdpc3RfYW92MywgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCmdpc3RfbHNkMyRjb21wYXJpc29uCgojIEtXIE5vbi1wYXJhbWV0cmljIHRlc3QgKGxpa2Ugb25lLXdheSBBTk9WQSkKa3J1c2thbC50ZXN0KGdpc3QgfiBtYWluZ3JvdXAsIGRhdGEgPSBhcy5tYXRyaXgoZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkpCgojIENoaSBTcQpnaXN0X2NoaXNxX3J2IDwtIHBhcnRpY2lwYW50X2RhdGEgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcihkaXJlY3Rpb24gPT0gInJldmVyc2VkIikgJT4lCiAgc2VsZWN0KG1haW5ncm91cCwgZ2lzdCkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBnaXN0KSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQogIHNwcmVhZChnaXN0LCBjb3VudCkgJT4lCiAgcmVuYW1lKG5vbmUgPSAiMCIsCiAgICAgICAgIG9uZSA9ICIwLjUiLAogICAgICAgICBib3RoID0gIjEiKQoKZ2lzdF9jaGlzcV9ydltpcy5uYShnaXN0X2NoaXNxX3J2KV0gPC0gMEwKZ2lzdF9jaGlzcV9ydiA8LSBjYmluZChnaXN0X2NoaXNxX3J2Wywibm9uZSJdLCBnaXN0X2NoaXNxX3J2Wywib25lIl0sIGdpc3RfY2hpc3FfcnZbLCJib3RoIl0pCmNoaXNxLnRlc3QoZ2lzdF9jaGlzcV9ydikKYGBgCgo0LiBBTkNPVkEgd2l0aCBmYWN0b3IgRGlyZWN0aW9uLCBhbmQgdmFyaWFibGVzIEFvQVNMIGFuZCBBZ2UuCgpgYGB7ciBnaXN0IGFub3ZhNCwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIEdpc3QgQU5PVkEgNApnaXN0X2FvdjQgPC0gYW92KGdpc3QgfiBkaXJlY3Rpb24gKiBhb2FzbCAqIGFnZSwgZGF0YSA9IHBhcnRpY2lwYW50X2RhdGEpCnN1bW1hcnkoZ2lzdF9hb3Y0KQpgYGAKCjUuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIEZvcndhcmQgb25seQoKYGBge3IgZ2lzdCBhbm92YTUsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBHaXN0IEFOT1ZBIDUKZ2lzdF9hb3Y1IDwtIGxtKGdpc3QgfiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShnaXN0X2FvdjUpCmBgYAoKNi4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBb0FTTCBhbmQgQWdlLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIGdpc3QgYW5vdmE2LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgR2lzdCBBTk9WQSA2Cmdpc3RfYW92NiA8LSBsbShnaXN0IH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIocGFydGljaXBhbnRfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KGdpc3RfYW92NikKYGBgCgojIyBMZXhpY2FsIFJlY2FsbCBBTk9WQXMKCjEuIEFOT1ZBIHdpdGggZmFjdG9ycyBNYWluR3JvdXAgJiBEaXJlY3Rpb24uCgpgYGB7ciBhY2MgYW5vdmExLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgTGV4aWNhbCBSZWNhbGwgQU5PVkEgMQphY2NfYW92MSA8LSBhb3YoYWNjIH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gcGFydGljaXBhbnRfZGF0YSkKc3VtbWFyeShhY2NfYW92MSkKYWNjX2xzZDEgPC0gTFNELnRlc3QoYWNjX2FvdjEsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQphY2NfbHNkMSRjb21wYXJpc29uCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgYWNjIGFub3ZhMiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIExleGljYWwgUmVjYWxsIEFOT1ZBIDIKYWNjX2FvdjIgPC0gYW92KGFjYyB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShhY2NfYW92MikKYWNjX2xzZDIgPC0gTFNELnRlc3QoYWNjX2FvdjIsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQphY2NfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIGFjYyBhbm92YTMsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBMZXhpY2FsIFJlY2FsbCBBTk9WQSAzCmFjY19hb3YzIDwtIGFvdihhY2MgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIocGFydGljaXBhbnRfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KGFjY19hb3YzKQphY2NfbHNkMyA8LSBMU0QudGVzdChhY2NfYW92MywgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCmFjY19sc2QzJGNvbXBhcmlzb24KYGBgCgo0LiBBTkNPVkEgd2l0aCBmYWN0b3IgRGlyZWN0aW9uLCBhbmQgY292YXJpYXRlIEFvQVNMIGFuZCBBZ2UuCgpgYGB7ciBhY2MgYW5vdmE0LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgTGV4aWNhbCBSZWNhbGwgQU5PVkEgNAphY2NfYW92NCA8LSBhb3YoYWNjIH4gZGlyZWN0aW9uICogYW9hc2wgKiBhZ2UsIGRhdGEgPSBwYXJ0aWNpcGFudF9kYXRhKQpzdW1tYXJ5KGFjY19hb3Y0KQpgYGAKCjUuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIEZvcndhcmQgb25seQoKYGBge3IgYWNjIGFub3ZhNSwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIExleGljYWwgUmVjYWxsIEFOT1ZBIDUKYWNjX2FvdjUgPC0gbG0oYWNjIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIocGFydGljaXBhbnRfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCnN1bW1hcnkoYWNjX2FvdjUpCmBgYAoKNi4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBb0FTTCBhbmQgQWdlLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIGFjYyBhbm92YTYsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBMZXhpY2FsIFJlY2FsbCBBTk9WQSA2CmFjY19hb3Y2IDwtIGxtKGFjYyB+IGFvYXNsICogYWdlLCBkYXRhID0gZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkKc3VtbWFyeShhY2NfYW92NikKYGBgCgoKIyBBb0EgQ29ycmVsYXRpb25zCgpOZXh0LCB3ZSB3YW50IHRvIGxvb2sgYXQgY29ycmVsYXRpb25zIGJldHdlZW4gQW9BIGFuZCBHaXN0LCBhbmQgYmV0d2VuIEFvQSBhbmQgTGV4aWNhbCBSZWNhbGwuIFJhaW4gYXNrZWQgZm9yIGZvcndhcmQgYW5kIHJldmVyc2VkIHNlcGFyYXRlbHkgKDEpIGRlYWYgb25seSwgKDIpIGhlYXJpbmcgb25seSwgYW5kICgzKSBib3RoLiBMZXQncyBtYWtlIGl0IHdvcmsuIAoKYGBge3IgcmVwYWNrYWdlIGRhdGEgZm9yIGNvcnJlbGF0aW9ucywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBMZXQncyBtYWtlIHBhcnRpY2lwYW50LWxldmVsIGRhdGEsIGFuZCBoYXZlIGZvcndhcmQvcmV2ZXJzZWQgaW4gc2VwYXJhdGUgY29sdW1ucwpsZXhnaXN0X2RhdGEgPC0gZnVsbGRhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBwYXJ0aWNpcGFudCwgZGlyZWN0aW9uKSAlPiUKICBtdXRhdGUoZ2lzdCA9IG1lYW4oZ2lzdCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgbGV4ID0gbWVhbihhY2MsIG5hLnJtID0gVFJVRSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBzZWxlY3QobWFpbmdyb3VwLCBwYXJ0aWNpcGFudCwgaGVhcmluZywgZGlyZWN0aW9uLCBhb2FzbCwgc2lnbnlycywgYWdlLCBnaXN0LCBsZXgpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgZ2F0aGVyKG1ldHJpYywgdmFsdWUsIGdpc3Q6bGV4KSAlPiUKICB1bml0ZShtZXRyaWN2YWx1ZSwgYyhtZXRyaWMsIGRpcmVjdGlvbiksIHNlcCA9ICJfIikgJT4lCiAgc3ByZWFkKG1ldHJpY3ZhbHVlLCB2YWx1ZSkgJT4lCiAgc2VsZWN0KC1wYXJ0aWNpcGFudCwgLW1haW5ncm91cCkKCmxleGdpc3RfZGVhZiA8LSBsZXhnaXN0X2RhdGEgJT4lIGZpbHRlcihoZWFyaW5nID09ICJEZWFmIikgJT4lIHNlbGVjdCgtaGVhcmluZykKbGV4Z2lzdF9oZWFyaW5nIDwtIGxleGdpc3RfZGF0YSAlPiUgZmlsdGVyKGhlYXJpbmcgPT0gIkhlYXJpbmciKSAlPiUgc2VsZWN0KC1oZWFyaW5nKQpsZXhnaXN0X2FsbCA8LSBsZXhnaXN0X2RhdGEgJT4lIHNlbGVjdCgtaGVhcmluZykKCiMgTG9hZCBhd2Vzb21lIGZ1bmN0aW9uIHRvIG1ha2UgY29ycmVsYXRpb24gdGFibGVzIHdpdGggc3RhcnMgZm9yIHNpZ25pZmljYW5jZQojIEZyb206IGh0dHBzOi8vbXlvd2VsdC5ibG9nc3BvdC5jby51ay8yMDA4LzA0L2JlYXV0aWZ1bC1jb3JyZWxhdGlvbi10YWJsZXMtaW4tci5odG1sCmNvcnN0YXJzbCA8LSBmdW5jdGlvbih4KXsgCnJlcXVpcmUoSG1pc2MpIAp4IDwtIGFzLm1hdHJpeCh4KSAKUiA8LSBIbWlzYzo6cmNvcnIoeCkkciAKcCA8LSBIbWlzYzo6cmNvcnIoeCkkUCAKIyMgZGVmaW5lIG5vdGlvbnMgZm9yIHNpZ25pZmljYW5jZSBsZXZlbHM7IHNwYWNpbmcgaXMgaW1wb3J0YW50LgpteXN0YXJzIDwtIGlmZWxzZShwIDwgLjAwMSwgIioqKiIsIGlmZWxzZShwIDwgLjAxLCAiKiogIiwgaWZlbHNlKHAgPCAuMDUsICIqICIsICIgIikpKQojIyB0cnVuY3R1YXRlIHRoZSBtYXRyaXggdGhhdCBob2xkcyB0aGUgY29ycmVsYXRpb25zIHRvIHR3byBkZWNpbWFsClIgPC0gZm9ybWF0KHJvdW5kKGNiaW5kKHJlcCgtMS4xMSwgbmNvbCh4KSksIFIpLCAyKSlbLC0xXSAKIyMgYnVpbGQgYSBuZXcgbWF0cml4IHRoYXQgaW5jbHVkZXMgdGhlIGNvcnJlbGF0aW9ucyB3aXRoIHRoZWlyIGFwcm9wcmlhdGUgc3RhcnMgClJuZXcgPC0gbWF0cml4KHBhc3RlKFIsIG15c3RhcnMsIHNlcD0iIiksIG5jb2w9bmNvbCh4KSkgCmRpYWcoUm5ldykgPC0gcGFzdGUoZGlhZyhSKSwgIiAiLCBzZXA9IiIpIApyb3duYW1lcyhSbmV3KSA8LSBjb2xuYW1lcyh4KSAKY29sbmFtZXMoUm5ldykgPC0gcGFzdGUoY29sbmFtZXMoeCksICIiLCBzZXA9IiIpIAojIyByZW1vdmUgdXBwZXIgdHJpYW5nbGUKUm5ldyA8LSBhcy5tYXRyaXgoUm5ldykKUm5ld1t1cHBlci50cmkoUm5ldywgZGlhZyA9IFRSVUUpXSA8LSAiIgpSbmV3IDwtIGFzLmRhdGEuZnJhbWUoUm5ldykgCiMjIHJlbW92ZSBsYXN0IGNvbHVtbiBhbmQgcmV0dXJuIHRoZSBtYXRyaXggKHdoaWNoIGlzIG5vdyBhIGRhdGEgZnJhbWUpClJuZXcgPC0gY2JpbmQoUm5ld1sxOmxlbmd0aChSbmV3KS0xXSkKcmV0dXJuKFJuZXcpIAp9CgojIENvcnJlbGF0aW9ucyBmb3IgRGVhZgpwcmludCgiREVBRiBDb3JyZWxhdGlvbnMgLSBQZWFyc29uJ3MgciIpCiNjb3JzdGFyc2wobGV4Z2lzdF9kZWFmKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGxleGdpc3RfZGVhZikpJHIKcHJpbnQoIkRFQUYgQ29ycmVsYXRpb25zIC0gUC12YWx1ZXMiKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGxleGdpc3RfZGVhZikpJFAKY2F0KHBhc3RlKCIiLCJcbiIsIiIpKQoKIyBDb3JyZWxhdGlvbnMgZm9yIEhlYXJpbmcKcHJpbnQoIkhFQVJJTkcgQ29ycmVsYXRpb25zIC0gUGVhcnNvbidzIHIiKQojY29yc3RhcnNsKGxleGdpc3RfaGVhcmluZykKSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChsZXhnaXN0X2hlYXJpbmcpKSRyCnByaW50KCJIRUFSSU5HIENvcnJlbGF0aW9ucyAtIFAtdmFsdWVzIikKSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChsZXhnaXN0X2hlYXJpbmcpKSRQCmNhdChwYXN0ZSgiIiwiXG4iLCIiKSkKCiMgQ29ycmVsYXRpb25zIGZvciBBbGwKcHJpbnQoIkFMTCBDb3JyZWxhdGlvbnMgLSBQZWFyc29uJ3MgciIpCiNjb3JzdGFyc2wobGV4Z2lzdF9hbGwpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgobGV4Z2lzdF9hbGwpKSRyCnByaW50KCJBTEwgQ29ycmVsYXRpb25zIC0gUC12YWx1ZXMiKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGxleGdpc3RfYWxsKSkkUAoKYGBgCgpJJ20gYWxzbyBpbmNsdWRpbmcgbmljZWx5IGZvcm1hdHRlZCB0YWJsZXMgd2l0aCAqKiogaW5kaWNhdG9ycyBvZiBzaWduaWZpY2FuY2UgZm9yIHF1aWNrIHJlZmVyZW5jaW5nLiBPcmRlcjogRGVhZiwgSGVhcmluZywgQWxsLiAKCmBgYHtyIHByZXR0eSBjb3JyZWxhdGlvbnN9CmNvcnN0YXJzbChsZXhnaXN0X2RlYWYpCmNvcnN0YXJzbChsZXhnaXN0X2hlYXJpbmcpCmNvcnN0YXJzbChsZXhnaXN0X2FsbCkKYGBgCgojIyBTY2F0dGVycGxvdCBvZiBDb3JyZWxhdGlvbnMKTGV0J3MgdmlzdWFsaXplIHdoYXQncyBoYXBwZW5pbmcgd2l0aCB0aGUgY29ycmVsYXRpb25zIGhlcmUuIApgYGB7ciBjb3JyZWxhdGlvbiBjaGFydHMsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZ2dwYWlycyhsZXhnaXN0X2RhdGEsIGNvbHVtbnMgPSBjKDI6OCksIGFlcyhjb2xvciA9IGhlYXJpbmcpKQpgYGAKCgojIEV5ZSBHYXplIERhdGEKCk5vdyBleWUgZ2F6ZSBkYXRhLiBCb3hwbG90cyBmaXJzdC4gQWxzbyBoZXJlLCB3ZSdyZSByZW5hbWluZyAiY2hpbiIgdG8gIm5lY2siIGJlY2F1c2UgdGhhdCdzIHdoYXQgaXQgYWN0dWFsbHkgaXMhIEJ1dCB3ZSBhbHNvIGhhdmUgdG8gZml4IGFsbCBOQSdzIGluIHRoZSBwZXJjZW50YWdlcyB0byB6ZXJvcywgYmVjdWFzZSB0aGF0J3Mgd2hhdCB0aGV5IGFjdHVhbGx5IGFyZS4gCmBgYHtyIGV5ZSBnYXplIGJveHBsb3R9CiMgcmVuYW1lIGNoaW4gdG8gbmVjawpmdWxsZGF0YSA8LSBmdWxsZGF0YSAlPiUKICByZW5hbWUobmVjayA9IGNoaW4pICU+JQogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OnVwcGVyY2hlc3QpCgojIEZpeCBhbGwgTkEncyBpbiBQZXJjZW50IGNvbHVtbiB0byAwCmZpeHBlcmNlbnQgPC0gZnVsbGRhdGEkcGVyY2VudApmdWxsZGF0YSRwZXJjZW50IDwtIGNvYWxlc2NlKGZpeHBlcmNlbnQsIDApCmZ1bGxkYXRhIDwtIGZ1bGxkYXRhICU+JQogIHNwcmVhZChhb2ksIHBlcmNlbnQpCgpmdWxsZGF0YSAlPiUKICBmaWx0ZXIoZXllX2V4Y2x1ZGUgPT0gRkFMU0UpICU+JQogIHNlbGVjdChkaXJlY3Rpb24sIGJlbGx5OnVwcGVyY2hlc3QpICU+JQogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OnVwcGVyY2hlc3QpICU+JQogIGdncGxvdChhZXMoeCA9IGFvaSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBkaXJlY3Rpb24pKSArIGdlb21fYm94cGxvdCgpCmBgYAoKIyMgRm9yZWhlYWQKVGhpcyBpcyBnb2luZyB0byBnZXQgY29tcGxpY2F0ZWQgLSB3ZSBuZWVkIHRvIHJ1biBhbGwgNiBBTk9WQXMvQU5DT1ZBcyBvbiA1IEFPSXMuIFRoYXQncyAzMCBtb2RlbHMuIFRoYW5rIGdvb2RuZXNzIGZvciBmaW5kLWFuZC1yZXBsYWNlISBJJ20gZ29pbmcgdG8gc2tpcCB0aGUgTFNEIGNvbXBhcmlzb25zIGZvciBub3csIHRvIG1ha2UgaXQgZWFzaWVyIHRvIGp1c3Qgc2Nyb2xsIHRocm91Z2guIAoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIGZvcmVoZWFkIGFub3ZhMSwgZWNobz1GQUxTRSwgcmVzdWx0cz0ibWFya3VwIn0KIyBGaXJzdCwgd2UndmUgZ290IHRvIHNldCB1cCB0aGUgZGF0YXNldC4gRGVmaW5lIHRoZSA1IEFPSXMKYW9pNSA8LSBjKCdmb3JlaGVhZCcsJ2V5ZXMnLCdtb3V0aCcsJ25lY2snLCd1cHBlcmNoZXN0JykKCiMgT3JnYW5pemUgdGhlIGRhdGEgYnkgdGhvc2UgQU9JcyAoYnV0IGFnYWluIHdlIG5lZWQgcGFydGljaXBhbnQtbGV2ZWwgZmlyc3QpCmFvaTVfZGF0YSA8LSBmdWxsZGF0YSAlPiUKICBmaWx0ZXIoZXllX2V4Y2x1ZGUgPT0gRkFMU0UpICU+JQogIHNlbGVjdChpZCwgbWFpbmdyb3VwLCBoZWFyaW5nLCBhb2FzbCwgYWdlLCBkaXJlY3Rpb24sIGJlbGx5OnVwcGVyY2hlc3QpICU+JQogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OnVwcGVyY2hlc3QpICU+JQogIGdyb3VwX2J5KGlkLCBkaXJlY3Rpb24sIGFvaSkgJT4lCiAgbXV0YXRlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtID0gVFJVRSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIGZpbHRlcihhb2kgJWluJSBhb2k1KSAlPiUKICBzcHJlYWQoYW9pLCBwZXJjZW50KQoKIyBmb3JlaGVhZCBBTkNPVkEgMQpmb3JlaGVhZF9hb3YxIDwtIGFvdihmb3JlaGVhZCB+IG1haW5ncm91cCAqIGRpcmVjdGlvbiwgZGF0YSA9IGFvaTVfZGF0YSkKc3VtbWFyeShmb3JlaGVhZF9hb3YxKQojIGZvcmVoZWFkX2xzZDEgPC0gTFNELnRlc3QoZm9yZWhlYWRfYW92MSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgZm9yZWhlYWRfbHNkMSRjb21wYXJpc29uCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgZm9yZWhlYWQgYW5vdmEyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJtYXJrdXAifQojIGZvcmVoZWFkIEFOT1ZBIDIKZm9yZWhlYWRfYW92MiA8LSBhb3YoZm9yZWhlYWQgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShmb3JlaGVhZF9hb3YyKQojIGZvcmVoZWFkX2xzZDIgPC0gTFNELnRlc3QoZm9yZWhlYWRfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgZm9yZWhlYWRfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIGZvcmVoZWFkIGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cz0ibWFya3VwIn0KIyBmb3JlaGVhZCBBTk9WQSAzCmZvcmVoZWFkX2FvdjMgPC0gYW92KGZvcmVoZWFkIH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKGFvaTVfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KGZvcmVoZWFkX2FvdjMpCiMgZm9yZWhlYWRfbHNkMyA8LSBMU0QudGVzdChmb3JlaGVhZF9hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBmb3JlaGVhZF9sc2QzJGNvbXBhcmlzb24KYGBgCgo0LiBBTkNPVkEgd2l0aCBmYWN0b3IgRGlyZWN0aW9uLCBhbmQgY292YXJpYXRlIEFvQVNMIGFuZCBBZ2UuCgpgYGB7ciBmb3JlaGVhZCBhbm92YTQsIGVjaG89RkFMU0UsIHJlc3VsdHM9Im1hcmt1cCJ9CiMgZm9yZWhlYWQgQU5PVkEgNApmb3JlaGVhZF9hb3Y0IDwtIGFvdihmb3JlaGVhZCB+IGRpcmVjdGlvbiAqIGFvYXNsICogYWdlLCBkYXRhID0gYW9pNV9kYXRhKQpzdW1tYXJ5KGZvcmVoZWFkX2FvdjQpCmBgYAoKNS4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgRm9yd2FyZCBvbmx5CgpgYGB7ciBmb3JlaGVhZCBhbm92YTUsIGVjaG89RkFMU0UsIHJlc3VsdHM9Im1hcmt1cCJ9CiMgZm9yZWhlYWQgQU5PVkEgNQpmb3JlaGVhZF9hb3Y1IDwtIGxtKGZvcmVoZWFkIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShmb3JlaGVhZF9hb3Y1KQpgYGAKCjYuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIFJldmVyc2Ugb25seQoKYGBge3IgZm9yZWhlYWQgYW5vdmE2LCBlY2hvPUZBTFNFLCByZXN1bHRzPSJtYXJrdXAifQojIGZvcmVoZWFkIEFOT1ZBIDYKZm9yZWhlYWRfYW92NiA8LSBsbShmb3JlaGVhZCB+IGFvYXNsICogYWdlLCBkYXRhID0gZmlsdGVyKGFvaTVfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KGZvcmVoZWFkX2FvdjYpCmBgYAoKIyMgRXllcwoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIGV5ZXMgYW5vdmExLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CgojIGV5ZXMgQU5DT1ZBIDEKZXllc19hb3YxIDwtIGFvdihleWVzIH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gYW9pNV9kYXRhKQpzdW1tYXJ5KGV5ZXNfYW92MSkKIyBleWVzX2xzZDEgPC0gTFNELnRlc3QoZXllc19hb3YxLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBleWVzX2xzZDEkY29tcGFyaXNvbgpgYGAKCjIuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIEZvcndhcmQgb25seS4KCmBgYHtyIGV5ZXMgYW5vdmEyLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgZXllcyBBTk9WQSAyCmV5ZXNfYW92MiA8LSBhb3YoZXllcyB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihhb2k1X2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGV5ZXNfYW92MikKIyBleWVzX2xzZDIgPC0gTFNELnRlc3QoZXllc19hb3YyLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBleWVzX2xzZDIkY29tcGFyaXNvbgpgYGAKCjMuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIFJldmVyc2Ugb25seS4gCgpgYGB7ciBleWVzIGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIGV5ZXMgQU5PVkEgMwpleWVzX2FvdjMgPC0gYW92KGV5ZXMgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkoZXllc19hb3YzKQojIGV5ZXNfbHNkMyA8LSBMU0QudGVzdChleWVzX2FvdjMsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIGV5ZXNfbHNkMyRjb21wYXJpc29uCmBgYAoKNC4gQU5DT1ZBIHdpdGggZmFjdG9yIERpcmVjdGlvbiwgYW5kIGNvdmFyaWF0ZSBBb0FTTCBhbmQgQWdlLgoKYGBge3IgZXllcyBhbm92YTQsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBleWVzIEFOT1ZBIDQKZXllc19hb3Y0IDwtIGFvdihleWVzIH4gZGlyZWN0aW9uICogYW9hc2wgKiBhZ2UsIGRhdGEgPSBhb2k1X2RhdGEpCnN1bW1hcnkoZXllc19hb3Y0KQpgYGAKCjUuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIEZvcndhcmQgb25seQoKYGBge3IgZXllcyBhbm92YTUsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBleWVzIEFOT1ZBIDUKZXllc19hb3Y1IDwtIGxtKGV5ZXMgfiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZpbHRlcihhb2k1X2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGV5ZXNfYW92NSkKYGBgCgo2LiBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFnZSBhbmQgQW9BU0wsIGZvciBSZXZlcnNlIG9ubHkKCmBgYHtyIGV5ZXMgYW5vdmE2LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgZXllcyBBTk9WQSA2CmV5ZXNfYW92NiA8LSBsbShleWVzIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkoZXllc19hb3Y2KQpgYGAKCiMjIE1vdXRoCgoxLiBBTk9WQSB3aXRoIGZhY3RvcnMgTWFpbkdyb3VwICYgRGlyZWN0aW9uLgoKYGBge3IgbW91dGggYW5vdmExLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CgojIG1vdXRoIEFOQ09WQSAxCm1vdXRoX2FvdjEgPC0gYW92KG1vdXRoIH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gYW9pNV9kYXRhKQpzdW1tYXJ5KG1vdXRoX2FvdjEpCm1vdXRoX2xzZDEgPC0gTFNELnRlc3QobW91dGhfYW92MSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCm1vdXRoX2xzZDEkY29tcGFyaXNvbgpgYGAKCjIuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIEZvcndhcmQgb25seS4KCmBgYHtyIG1vdXRoIGFub3ZhMiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG1vdXRoIEFOT1ZBIDIKbW91dGhfYW92MiA8LSBhb3YobW91dGggfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShtb3V0aF9hb3YyKQojIG1vdXRoX2xzZDIgPC0gTFNELnRlc3QobW91dGhfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgbW91dGhfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIG1vdXRoIGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG1vdXRoIEFOT1ZBIDMKbW91dGhfYW92MyA8LSBhb3YobW91dGggfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkobW91dGhfYW92MykKIyBtb3V0aF9sc2QzIDwtIExTRC50ZXN0KG1vdXRoX2FvdjMsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIG1vdXRoX2xzZDMkY29tcGFyaXNvbgpgYGAKCjQuIEFOQ09WQSB3aXRoIGZhY3RvciBEaXJlY3Rpb24sIGFuZCBjb3ZhcmlhdGUgQW9BU0wgYW5kIEFnZS4KCmBgYHtyIG1vdXRoIGFub3ZhNCwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG1vdXRoIEFOT1ZBIDQKbW91dGhfYW92NCA8LSBhb3YobW91dGggfiBkaXJlY3Rpb24gKiBhb2FzbCAqIGFnZSwgZGF0YSA9IGFvaTVfZGF0YSkKc3VtbWFyeShtb3V0aF9hb3Y0KQpgYGAKCjUuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIEZvcndhcmQgb25seQoKYGBge3IgbW91dGggYW5vdmE1LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgbW91dGggQU5PVkEgNQptb3V0aF9hb3Y1IDwtIGxtKG1vdXRoIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShtb3V0aF9hb3Y1KQpgYGAKCjYuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIFJldmVyc2Ugb25seQoKYGBge3IgbW91dGggYW5vdmE2LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgbW91dGggQU5PVkEgNgptb3V0aF9hb3Y2IDwtIGxtKG1vdXRoIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkobW91dGhfYW92NikKYGBgCgojIyBOZWNrCgoxLiBBTk9WQSB3aXRoIGZhY3RvcnMgTWFpbkdyb3VwICYgRGlyZWN0aW9uLgoKYGBge3IgbmVjayBhbm92YTEsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KCiMgbmVjayBBTkNPVkEgMQpuZWNrX2FvdjEgPC0gYW92KG5lY2sgfiBtYWluZ3JvdXAgKiBkaXJlY3Rpb24sIGRhdGEgPSBhb2k1X2RhdGEpCnN1bW1hcnkobmVja19hb3YxKQojIG5lY2tfbHNkMSA8LSBMU0QudGVzdChuZWNrX2FvdjEsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIG5lY2tfbHNkMSRjb21wYXJpc29uCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgbmVjayBhbm92YTIsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBuZWNrIEFOT1ZBIDIKbmVja19hb3YyIDwtIGFvdihuZWNrIH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKGFvaTVfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCnN1bW1hcnkobmVja19hb3YyKQojIG5lY2tfbHNkMiA8LSBMU0QudGVzdChuZWNrX2FvdjIsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIG5lY2tfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIG5lY2sgYW5vdmEzLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgbmVjayBBTk9WQSAzCm5lY2tfYW92MyA8LSBhb3YobmVjayB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihhb2k1X2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkKc3VtbWFyeShuZWNrX2FvdjMpCiMgbmVja19sc2QzIDwtIExTRC50ZXN0KG5lY2tfYW92MywgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgbmVja19sc2QzJGNvbXBhcmlzb24KYGBgCgo0LiBBTkNPVkEgd2l0aCBmYWN0b3IgRGlyZWN0aW9uLCBhbmQgY292YXJpYXRlIEFvQVNMIGFuZCBBZ2UuCgpgYGB7ciBuZWNrIGFub3ZhNCwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG5lY2sgQU5PVkEgNApuZWNrX2FvdjQgPC0gYW92KG5lY2sgfiBkaXJlY3Rpb24gKiBhb2FzbCAqIGFnZSwgZGF0YSA9IGFvaTVfZGF0YSkKc3VtbWFyeShuZWNrX2FvdjQpCmBgYAoKNS4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgRm9yd2FyZCBvbmx5CgpgYGB7ciBuZWNrIGFub3ZhNSwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG5lY2sgQU5PVkEgNQpuZWNrX2FvdjUgPC0gbG0obmVjayB+IGFvYXNsICogYWdlLCBkYXRhID0gZmlsdGVyKGFvaTVfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCnN1bW1hcnkobmVja19hb3Y1KQpgYGAKCjYuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIFJldmVyc2Ugb25seQoKYGBge3IgbmVjayBhbm92YTYsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBuZWNrIEFOT1ZBIDYKbmVja19hb3Y2IDwtIGxtKG5lY2sgfiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZpbHRlcihhb2k1X2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkKc3VtbWFyeShuZWNrX2FvdjYpCmBgYAoKIyMgVXBwZXJjaGVzdAoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIHVwcGVyY2hlc3QgYW5vdmExLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CgojIHVwcGVyY2hlc3QgQU5DT1ZBIDEKdXBwZXJjaGVzdF9hb3YxIDwtIGFvdih1cHBlcmNoZXN0IH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gYW9pNV9kYXRhKQpzdW1tYXJ5KHVwcGVyY2hlc3RfYW92MSkKdXBwZXJjaGVzdF9sc2QxIDwtIExTRC50ZXN0KHVwcGVyY2hlc3RfYW92MSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCnVwcGVyY2hlc3RfbHNkMSRjb21wYXJpc29uCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgdXBwZXJjaGVzdCBhbm92YTIsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyB1cHBlcmNoZXN0IEFOT1ZBIDIKdXBwZXJjaGVzdF9hb3YyIDwtIGFvdih1cHBlcmNoZXN0IH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKGFvaTVfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCnN1bW1hcnkodXBwZXJjaGVzdF9hb3YyKQojIHVwcGVyY2hlc3RfbHNkMiA8LSBMU0QudGVzdCh1cHBlcmNoZXN0X2FvdjIsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIHVwcGVyY2hlc3RfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIHVwcGVyY2hlc3QgYW5vdmEzLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgdXBwZXJjaGVzdCBBTk9WQSAzCnVwcGVyY2hlc3RfYW92MyA8LSBhb3YodXBwZXJjaGVzdCB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihhb2k1X2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkKc3VtbWFyeSh1cHBlcmNoZXN0X2FvdjMpCnVwcGVyY2hlc3RfbHNkMyA8LSBMU0QudGVzdCh1cHBlcmNoZXN0X2FvdjMsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQp1cHBlcmNoZXN0X2xzZDMkY29tcGFyaXNvbgpgYGAKCjQuIEFOQ09WQSB3aXRoIGZhY3RvciBEaXJlY3Rpb24sIGFuZCBjb3ZhcmlhdGUgQW9BU0wgYW5kIEFnZS4KCmBgYHtyIHVwcGVyY2hlc3QgYW5vdmE0LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgdXBwZXJjaGVzdCBBTk9WQSA0CnVwcGVyY2hlc3RfYW92NCA8LSBhb3YodXBwZXJjaGVzdCB+IGRpcmVjdGlvbiAqIGFvYXNsICogYWdlLCBkYXRhID0gYW9pNV9kYXRhKQpzdW1tYXJ5KHVwcGVyY2hlc3RfYW92NCkKYGBgCgo1LiBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFnZSBhbmQgQW9BU0wsIGZvciBGb3J3YXJkIG9ubHkKCmBgYHtyIHVwcGVyY2hlc3QgYW5vdmE1LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgdXBwZXJjaGVzdCBBTk9WQSA1CnVwcGVyY2hlc3RfYW92NSA8LSBsbSh1cHBlcmNoZXN0IH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoYW9pNV9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeSh1cHBlcmNoZXN0X2FvdjUpCmBgYAoKNi4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgUmV2ZXJzZSBvbmx5CgpgYGB7ciB1cHBlcmNoZXN0IGFub3ZhNiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIHVwcGVyY2hlc3QgQU5PVkEgNgp1cHBlcmNoZXN0X2FvdjYgPC0gbG0odXBwZXJjaGVzdCB+IGFvYXNsICogYWdlLCBkYXRhID0gZmlsdGVyKGFvaTVfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KHVwcGVyY2hlc3RfYW92NikKYGBgCgojIyBGYWNlQ2hlc3QKCldlIG9yaWdpbmFsbHkgZGVmaW5lZCBGYWNlQ2hlc3Qgc3VjaCB0aGF0CgoxLiBGYWNlID0gZXllcyArIG1vdXRoICsgY2hpbgoxLiBDaGVzdCA9IHVwcGVyY2hlc3QgKyBtaWRjaGVzdCArIGxvd2VyY2hlc3QKCkJVVC4gQ2hpbiBpcyBhY3R1YWxseSBuZWNrLiBJdCdzIG5vdCBldmVuIHBhcnQgb2YgdGhlIGZhY2UgaWYgeW91IHRoaW5rIGFib3V0IGl0LiBTbyBJJ20gcmVkZWZpbmluZyBGYWNlQ2hlc3QgYXM6CgoxLiBGYWNlID0gZm9yZWhlYWQgKyBleWVzICsgbW91dGgKMS4gQ2hlc3QgPSBuZWNrICsgdXBwZXJjaGVzdCArIG1pZGNoZXN0ICsgbG93ZXJjaGVzdAoKU28gbGV0J3MgZG8gdGhpcy4gVGhlbiBzZWUgd2hhdCdzIGhhcHBlbmluZyBhY3Jvc3MgZ3JvdXBzIGZvciBGYWNlQ2hlc3QuCgpgYGB7ciBjYWxjdWxhdGUgZmFjZWNoZXN0LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgQ2FsY3VsYXRlIGZhY2UsIGNoZXN0LCBhbmQgZmFjZWNoZXN0IC0gYW5kIG1vdXRoZXllIHRvbwpmdWxsZGF0YSA8LSBmdWxsZGF0YSAlPiUKICByb3d3aXNlKCkgJT4lCiAgbXV0YXRlKGZhY2UgPSBzdW0oZm9yZWhlYWQsIGV5ZXMsIG1vdXRoLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICBjaGVzdCA9IHN1bShuZWNrLCB1cHBlcmNoZXN0LCBtaWRjaGVzdCwgbG93ZXJjaGVzdCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgZmFjZWNoZXN0ID0gKGZhY2UgLSBjaGVzdCkvKGZhY2UgKyBjaGVzdCksCiAgICAgICAgIG1vdXRoZXllID0gKG1vdXRoIC0gZXllcykvKG1vdXRoICsgZXllcykpCgojIGZ1bGxkYXRhICU+JSAKIyAgIGdhdGhlcihtZXRyaWMsIHZhbHVlLCBjKGZhY2VjaGVzdF9vbGQsIGZhY2VjaGVzdCkpICU+JQojICAgZ2dwbG90KGFlcyh4ID0gbWFpbmdyb3VwLCB5ID0gdmFsdWUsIGZpbGwgPSBkaXJlY3Rpb24pKSArIGdlb21fYm94cGxvdCgpICsgZmFjZXRfd3JhcCgibWV0cmljIikKYGBgCgpDb29sLiBOZXh0IHdlJ2xsIGRvIGVycm9yIGJhciBjaGFydHMgdXNpbmcgdGhlIG5ldyBGYWNlQ2hlc3QgYWNyb3NzIGdyb3Vwcy4gCgpgYGB7ciBmYWNlY2hlc3QgYmFycywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZmFjZWNoZXN0X2luZm8gPC0gZnVsbGRhdGEgJT4lCiAgZmlsdGVyKGV5ZV9leGNsdWRlID09IEZBTFNFKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbiwgcGFydGljaXBhbnQpICU+JQogIHN1bW1hcmlzZShmYWNlY2hlc3QgPSBtZWFuKGZhY2VjaGVzdCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihmYWNlY2hlc3QpLAogICAgICAgICAgICBzZCA9IHNkKGZhY2VjaGVzdCksCiAgICAgICAgICAgIG4gPSBuKCksCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChuKSkKCmdncGxvdChmYWNlY2hlc3RfaW5mbywgYWVzKHggPSBtYWluZ3JvdXAsIHkgPSBtZWFuLCBmaWxsID0gZGlyZWN0aW9uLCBjb2xvciA9IGRpcmVjdGlvbikpICsKICBnZW9tX3BvaW50KHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNSksIHNpemUgPSAyKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuLXNlLCB5bWF4ID0gbWVhbitzZSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC41KSwgd2lkdGggPSAwLjMsIHNpemUgPSAxKSArCiAgbGFicyh0aXRsZSA9ICJGYWNlQ2hlc3QgUmF0aW8iLCBzdWJ0aXRsZSA9ICJFcnJvciBiYXJzIHJlcHJlc2VudCBTRSIsIHggPSAiIiwgeSA9ICJmYWNlY2hlc3QgcmF0aW8iKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsMSkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZG90dGVkIikKYGBgCgpOb3cgbGV0J3MgZG8gdGhlIEFOT1ZBcy4gQWxzbyBza2lwcGluZyBMU0RzIGhlcmUuIAoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIGZhY2VjaGVzdCBhbm92YSAxLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCcsIG1lc3NhZ2U9RkFMU0V9CiMgQ3JlYXRlIHRoZSBwYXJ0aWNpcGFudC1sZXZlbCBkYiAobGV0J3MgYWxzbyBwb3AgbW91dGhleWUgaW4gdGhpcyB0b28pCmZjX2RhdGEgPC0gZnVsbGRhdGEgJT4lCiAgZmlsdGVyKGV5ZV9leGNsdWRlID09IEZBTFNFKSAlPiUKICBzZWxlY3QoaWQsIG1haW5ncm91cCwgaGVhcmluZywgYW9hc2wsIGFnZSwgZGlyZWN0aW9uLCBmYWNlY2hlc3QsIG1vdXRoZXllKSAlPiUKICBncm91cF9ieShpZCwgZGlyZWN0aW9uKSAlPiUKICBtdXRhdGUoZmFjZWNoZXN0ID0gbWVhbihmYWNlY2hlc3QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIG1vdXRoZXllID0gbWVhbihtb3V0aGV5ZSwgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGRpc3RpbmN0KCkKCiMgZmFjZWNoZXN0IEFOQ09WQSAxCmZhY2VjaGVzdF9hb3YxIDwtIGFvdihmYWNlY2hlc3QgfiBtYWluZ3JvdXAgKiBkaXJlY3Rpb24sIGRhdGEgPSBmY19kYXRhKQpzdW1tYXJ5KGZhY2VjaGVzdF9hb3YxKQojIGZhY2VjaGVzdF9sc2QxIDwtIExTRC50ZXN0KGZhY2VjaGVzdF9hb3YxLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBmYWNlY2hlc3RfbHNkMSRjb21wYXJpc29uCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgZmFjZWNoZXN0IGFub3ZhMiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIGZhY2VjaGVzdCBBTk9WQSAyCmZhY2VjaGVzdF9hb3YyIDwtIGFvdihmYWNlY2hlc3QgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoZmNfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCnN1bW1hcnkoZmFjZWNoZXN0X2FvdjIpCiMgZmFjZWNoZXN0X2xzZDIgPC0gTFNELnRlc3QoZmFjZWNoZXN0X2FvdjIsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIGZhY2VjaGVzdF9sc2QyJGNvbXBhcmlzb24KYGBgCgozLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBSZXZlcnNlIG9ubHkuIAoKYGBge3IgZmFjZWNoZXN0IGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIGZhY2VjaGVzdCBBTk9WQSAzCmZhY2VjaGVzdF9hb3YzIDwtIGFvdihmYWNlY2hlc3QgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoZmNfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KGZhY2VjaGVzdF9hb3YzKQojIGZhY2VjaGVzdF9sc2QzIDwtIExTRC50ZXN0KGZhY2VjaGVzdF9hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBmYWNlY2hlc3RfbHNkMyRjb21wYXJpc29uCmBgYAoKNC4gQU5DT1ZBIHdpdGggZmFjdG9yIERpcmVjdGlvbiwgYW5kIGNvdmFyaWF0ZSBBb0FTTCBhbmQgQWdlLgoKYGBge3IgZmFjZWNoZXN0IGFub3ZhNCwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIGZhY2VjaGVzdCBBTk9WQSA0CmZhY2VjaGVzdF9hb3Y0IDwtIGFvdihmYWNlY2hlc3QgfiBkaXJlY3Rpb24gKiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZjX2RhdGEpCnN1bW1hcnkoZmFjZWNoZXN0X2FvdjQpCmBgYAoKNS4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgRm9yd2FyZCBvbmx5CgpgYGB7ciBmYWNlY2hlc3QgYW5vdmE1LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgZmFjZWNoZXN0IEFOT1ZBIDUKZmFjZWNoZXN0X2FvdjUgPC0gbG0oZmFjZWNoZXN0IH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoZmNfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCnN1bW1hcnkoZmFjZWNoZXN0X2FvdjUpCmBgYAoKNi4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgUmV2ZXJzZSBvbmx5CgpgYGB7ciBmYWNlY2hlc3QgYW5vdmE2LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgZmFjZWNoZXN0IEFOT1ZBIDYKZmFjZWNoZXN0X2FvdjYgPC0gbG0oZmFjZWNoZXN0IH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoZmNfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KGZhY2VjaGVzdF9hb3Y2KQpgYGAKCgojIyBNb3V0aEV5ZQpXZSd2ZSBhbHNvIGdvdCBhIG1vdXRoZXllIHJhdGlvISBNYXliZSBzb21ldGhpbmcgdGhlcmUsIHRvby4KYGBge3IgbW91dGhleWUgYmFyIGNoYXJ0LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQptb3V0aGV5ZV9pbmZvIDwtIGZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24sIHBhcnRpY2lwYW50KSAlPiUKICBzdW1tYXJpc2UobW91dGhleWUgPSBtZWFuKG1vdXRoZXllLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKG1vdXRoZXllLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBzZCA9IHNkKG1vdXRoZXllLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBuID0gbigpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQobikpCgpnZ3Bsb3QobW91dGhleWVfaW5mbywgYWVzKHggPSBtYWluZ3JvdXAsIHkgPSBtZWFuLCBmaWxsID0gZGlyZWN0aW9uLCBjb2xvciA9IGRpcmVjdGlvbikpICsKICBnZW9tX3BvaW50KHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNSksIHNpemUgPSAyKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuLXNlLCB5bWF4ID0gbWVhbitzZSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC41KSwgd2lkdGggPSAwLjMsIHNpemUgPSAxKSArCiAgbGFicyh0aXRsZSA9ICJNb3V0aEV5ZSBSYXRpbyIsIHN1YnRpdGxlID0gIkVycm9yIGJhcnMgcmVwcmVzZW50IFNFIiwgeCA9ICIiLCB5ID0gIm1vdXRoZXllIHJhdGlvIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0xLDEpKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRvdHRlZCIpCmBgYAoKQW5kIE1vdXRoZXllIEFOT1ZBcy4gQWxzbyBza2lwcGluZyBMU0RzIGhlcmUuIAoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIG1vdXRoZXllIGFub3ZhIDEsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBtb3V0aGV5ZSBBTkNPVkEgMQptb3V0aGV5ZV9hb3YxIDwtIGFvdihtb3V0aGV5ZSB+IG1haW5ncm91cCAqIGRpcmVjdGlvbiwgZGF0YSA9IGZjX2RhdGEpCnN1bW1hcnkobW91dGhleWVfYW92MSkKbW91dGhleWVfbHNkMSA8LSBMU0QudGVzdChtb3V0aGV5ZV9hb3YxLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKbW91dGhleWVfbHNkMSRjb21wYXJpc29uCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgbW91dGhleWUgYW5vdmEyLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgbW91dGhleWUgQU5PVkEgMgptb3V0aGV5ZV9hb3YyIDwtIGFvdihtb3V0aGV5ZSB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihmY19kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShtb3V0aGV5ZV9hb3YyKQojIG1vdXRoZXllX2xzZDIgPC0gTFNELnRlc3QobW91dGhleWVfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgbW91dGhleWVfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIG1vdXRoZXllIGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG1vdXRoZXllIEFOT1ZBIDMKbW91dGhleWVfYW92MyA8LSBhb3YobW91dGhleWUgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoZmNfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KG1vdXRoZXllX2FvdjMpCiMgbW91dGhleWVfbHNkMyA8LSBMU0QudGVzdChtb3V0aGV5ZV9hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBtb3V0aGV5ZV9sc2QzJGNvbXBhcmlzb24KYGBgCgo0LiBBTkNPVkEgd2l0aCBmYWN0b3IgRGlyZWN0aW9uLCBhbmQgY292YXJpYXRlIEFvQVNMIGFuZCBBZ2UuCgpgYGB7ciBtb3V0aGV5ZSBhbm92YTQsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBtb3V0aGV5ZSBBTk9WQSA0Cm1vdXRoZXllX2FvdjQgPC0gYW92KG1vdXRoZXllIH4gZGlyZWN0aW9uICogYW9hc2wgKiBhZ2UsIGRhdGEgPSBmY19kYXRhKQpzdW1tYXJ5KG1vdXRoZXllX2FvdjQpCmBgYAoKNS4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgRm9yd2FyZCBvbmx5CgpgYGB7ciBtb3V0aGV5ZSBhbm92YTUsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBtb3V0aGV5ZSBBTk9WQSA1Cm1vdXRoZXllX2FvdjUgPC0gbG0obW91dGhleWUgfiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZpbHRlcihmY19kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShtb3V0aGV5ZV9hb3Y1KQpgYGAKCjYuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIFJldmVyc2Ugb25seQoKYGBge3IgbW91dGhleWUgYW5vdmE2LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgbW91dGhleWUgQU5PVkEgNgptb3V0aGV5ZV9hb3Y2IDwtIGxtKG1vdXRoZXllIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoZmNfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KG1vdXRoZXllX2FvdjYpCmBgYAoKIyBIZWF0IE1hcHMKQW5kIGZpbmFsbHksIHdlJ3JlIGdvaW5nIHRvIGRvIGhlYXQgbWFwcy4gCmBgYHtyIGhlYXQgbWFwfQpleWVnYXplX2hlYXQgPC0gZnVsbGRhdGEgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgc2VsZWN0KGlkOmRpcmVjdGlvbiwgYmVsbHksIGxvd2VyY2hlc3QsIG1pZGNoZXN0LCB1cHBlcmNoZXN0LCBuZWNrLCBtb3V0aCwgZXllcywgZm9yZWhlYWQpICU+JQogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OmZvcmVoZWFkKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBkaXJlY3Rpb24sIGFvaSkgJT4lCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtPVRSVUUpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsZGlyZWN0aW9uLGFvaSkgJT4lCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtPVRSVUUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKCFpcy5uYShhb2kpKSAlPiUKICBtdXRhdGUoYW9pID0gZmFjdG9yKGFvaSxsZXZlbHM9YygiYmVsbHkiLCJsb3dlcmNoZXN0IiwibWlkY2hlc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1cHBlcmNoZXN0IiwibmVjayIsIm1vdXRoIiwiZXllcyIsImZvcmVoZWFkIikpKQoKZXllZ2F6ZV9oZWF0X2FsbCA8LSBmdWxsZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKGV5ZV9leGNsdWRlID09IEZBTFNFKSAlPiUKICBzZWxlY3QoaWQ6ZGlyZWN0aW9uLCBiZWxseSwgbG93ZXJjaGVzdCwgbWlkY2hlc3QsIHVwcGVyY2hlc3QsIG5lY2ssIG1vdXRoLCBleWVzLCBmb3JlaGVhZCkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6Zm9yZWhlYWQpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCxwYXJ0aWNpcGFudCxkaXJlY3Rpb24sYW9pKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtPVRSVUUpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsZGlyZWN0aW9uLGFvaSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShwZXJjZW50ID0gbWVhbihwZXJjZW50LCBuYS5ybT1UUlVFKSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLGFvaSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShwZXJjZW50ID0gbWVhbihwZXJjZW50LCBuYS5ybT1UUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcighaXMubmEoYW9pKSkgJT4lCiAgbXV0YXRlKGFvaSA9IGZhY3Rvcihhb2ksbGV2ZWxzPWMoImJlbGx5IiwibG93ZXJjaGVzdCIsIm1pZGNoZXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidXBwZXJjaGVzdCIsIm5lY2siLCJtb3V0aCIsImV5ZXMiLCJmb3JlaGVhZCIpKSkKCmdncGxvdChleWVnYXplX2hlYXQsIGFlcyh4ID0gbWFpbmdyb3VwLCB5ID0gYW9pKSkgKwogIGdlb21fdGlsZShhZXMoZmlsbD1wZXJjZW50KSxjb2xvcj0ibGlnaHRncmF5IixuYS5ybT1UUlVFKSArIAojICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJsaWdodGJsdWUiLGhpZ2ggPSAic3RlZWxibHVlIikgKwojICBzY2FsZV9maWxsX2Rpc3RpbGxlcih0eXBlPSJkaXYiLCBwYWxldHRlID0gIlJkWWxCdSIpICsKICBzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gInZpcmlkaXMiLCBkaXJlY3Rpb249LTEsIGxpbWl0cyA9IGMoMCwuNzUpKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LGhqdXN0PTEpKSArIGZhY2V0X2dyaWQoLiB+IGRpcmVjdGlvbikgKwogIHlsYWIoIiIpICsgeGxhYigiIikgKyBnZ3RpdGxlKCJFeWUgR2F6ZSBIZWF0IE1hcCwgYnkgRGlyZWN0aW9uIikKCmdncGxvdChleWVnYXplX2hlYXRfYWxsLCBhZXMoeCA9IG1haW5ncm91cCwgeSA9IGFvaSkpICsKICBnZW9tX3RpbGUoYWVzKGZpbGw9cGVyY2VudCksY29sb3I9ImxpZ2h0Z3JheSIsbmEucm09VFJVRSkgKyAKIyAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAibGlnaHRibHVlIixoaWdoID0gInN0ZWVsYmx1ZSIpICsKIyAgc2NhbGVfZmlsbF9kaXN0aWxsZXIodHlwZT0iZGl2IiwgcGFsZXR0ZSA9ICJSZFlsQnUiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzKG9wdGlvbiA9ICJ2aXJpZGlzIiwgZGlyZWN0aW9uPS0xLCBsaW1pdHMgPSBjKDAsLjc1KSkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT00NSxoanVzdD0xKSkgKwogIHlsYWIoIiIpICsgeGxhYigiIikgKyBnZ3RpdGxlKCJFeWUgR2F6ZSBIZWF0IE1hcCAoRGlyZWN0aW9uIENvbGxhcHNlZCkiKQpgYGAKCiMgU3VtbWFyeQoKQmVsb3cgYXJlIHRoZSBwLXZhbHVlcyBmcm9tIHRoZSBBTk9WQXMgd2l0aCA0IE1haW5Hcm91cHMuIEkgbmV2ZXIgaW5jbHVkZWQgQWdlIGFzIGEgY292YXJpYXRlIGJlY2F1c2UgaXQgbmV2ZXIgaW1wcm92ZWQgdGhlIG1vZGVsLiBJIGluY2x1ZGVkIGFsbCBBTk9WQXMgZm9yIEdpc3QgYW5kIExleCBSZWNhbGwsIGFuZCBBTk9WQXMgZm9yIGFueSBleWUgQU9JIG9yIHJhdGlvIHdhcyBpbmNsdWRlZCBvbmx5IGlmIGVpdGhlciBtYWluZ3JvdXAgb3IgZGlyZWN0aW9uIHdhcyBzaWduaWZpY2FudC4gRGVhZmVhcmx5LURlYWZsYXRlIHNob3dzIHRoZSBMU0QgcC12YWx1ZSBmb3IgdGhhdCBjb21wYXJpc29uLgpgYGB7ciByZXN1bHRzMSwgcm93cy5wcmludCA9IDIwfQpyZXN1bHRzMSA8LSBzdHJ1Y3R1cmUobGlzdChtb2RlbCA9IGMoImdpc3QtbWFpbmdyb3VwLWJvdGgiLCAiZ2lzdC1tYWluZ3JvdXAtZnciLCAKImdpc3QtbWFpbmdyb3VwLXJ2IiwgImxleHJlY2FsbC1tYWluZ3JvdXAtYm90aCIsICJsZXhyZWNhbGwtbWFpbmdyb3VwLWZ3IiwgCiJsZXhyZWNhbGwtbWFpbmdyb3VwLXJ2IiwgIm1vdXRoLW1haW5ncm91cC1ib3RoIiwgInVwcGVyY2hlc3QtbWFpbmdyb3VwLWJvdGgiLCAKInVwcGVyY2hlc3QtbWFpbmdyb3VwLXJ2IiwgImZhY2VjaGVzdC1tYWluZ3JvdXAtYm90aCIsICJtb3V0aGV5ZS1tYWluZ3JvdXAtYm90aCIKKSwgbWFpbmdyb3VwID0gYygwLCAwLCAwLjAxLCAwLCAwLjA0LCAwLjAyLCAwLjA2LCAwLCAwLjAxLCAwLjEsIAowLjA1KSwgZGlyZWN0aW9uID0gYygwLCBOQSwgTkEsIDAsIE5BLCBOQSwgMC4wNiwgMC4xNiwgTkEsIDAuMDcsIAowLjQ4KSwgYGRlYWZlYXJseS1kZWFmbGF0ZWAgPSBjKDAuMSwgMC42OSwgMC4wMiwgMC4xMSwgMC45NSwgCjAuMDYsIDAuMzgsIDAuOTQsIDAuNTIsIDAuMDgsIDAuNjgpKSwgLk5hbWVzID0gYygibW9kZWwiLCAibWFpbmdyb3VwIiwgCiJkaXJlY3Rpb24iLCAiZGVhZmVhcmx5LWRlYWZsYXRlIiksIGNsYXNzID0gYygidGJsX2RmIiwgInRibCIsIAoiZGF0YS5mcmFtZSIpLCByb3cubmFtZXMgPSBjKE5BLCAtMTFMKSkKCnJlc3VsdHMxCmBgYAoKQW5kIGJlbG93IGFyZSB0aGUgcC12YWx1ZXMgZnJvbSB0aGUgQU5DT1ZBcyB3aXRoIEhlYXJpbmcgJiBBb0FTTC4gSSBpbmNsdWRlZCBhbGwgQU5DT1ZBcyBmb3IgR2lzdCBhbmQgTGV4IFJlY2FsbCwgYW5kIEFOQ09WQXMgZm9yIGFueSBleWUgQU9JIG9yIHJhdGlvIHdhcyBpbmNsdWRlZCBvbmx5IGlmIGFueSBtYWluIGZhY3RvciB3YXMgc2lnbmlmaWNhbnQuIExTRCBjb21wYXJpc29ucyBhcmUgbm90IG5lZWRlZCBiZWNhdXNlIHRoZXJlJ3Mgb25seSAyIGxldmVscyBpbiBlYWNoIGdyb3VwIQoKYGBge3IgcmVzdWx0czIsIHJvd3MucHJpbnQgPSAyNX0KcmVzdWx0czIgPC0gc3RydWN0dXJlKGxpc3QobW9kZWwgPSBjKCJnaXN0LWJvdGgiLCAiZ2lzdC1mdyIsICJnaXN0LXJ2IiwgImxleC1ib3RoIiwgCiJsZXgtZnciLCAibGV4LXJ2IiwgImZvcmVoZWFkLWZ3IiwgIm1vdXRoLWJvdGgiLCAibW91dGgtcnYiLCAKInVwcGVyY2hlc3QtYm90aCIsICJ1cHBlcmNoZXN0LXJ2IiwgImZhY2VjaGVzdC1ib3RoIiwgIm1vdXRoZXllLWJvdGgiCiksIGhlYXJpbmcgPSBjKDAsIDAuMDAsIDAuMDEsIDAuMDEsIDAuMjIsIDAuMDMsIDAuMDYsIDAuMDEsIAowLjA0LCAwLjAxLCAwLjAxLCAwLjM1LCAwLjA3KSwgZGlyZWN0aW9uID0gYygwLCBOQSwgTkEsIDAsIE5BLCAKTkEsIE5BLCAwLjA1LCBOQSwgMC4yMSwgTkEsIDAuMDUsIDAuNTIpLCBhb2FzbCA9IGMoMC4yMiwgMC43NywgCjAuMTksIDAuNTYsIDAuNTgsIDAuMjUsIDAuMDgsIDAuMDYsIDAuMTIsIDAuNjgsIDAuOTUsIDAuMTIsIDAuNDQKKSwgYWdlID0gYygwLjA4LCAwLjAxLCAwLjg2LCAwLjA5LCAwLjAyLCAwLjcsIDAuNjgsIDAuMjgsIDAuNSwgCjAuMDIsIDAuMDgsIDAuMDAsIDAuMjEpKSwgLk5hbWVzID0gYygibW9kZWwiLCAiaGVhcmluZyIsICJkaXJlY3Rpb24iLCAKImFvYXNsIiwgImFnZSIpLCBjbGFzcyA9IGMoInRibF9kZiIsICJ0YmwiLCAiZGF0YS5mcmFtZSIpLCByb3cubmFtZXMgPSBjKE5BLCAKLTEzTCkpCnJlc3VsdHMyCmBgYAoKRmluYWxseSwgdGhlIGNvcnJlbGF0aW9ucyBmb3IgRGVhZiBhbmQgSGVhcmluZyBzZXBhcmF0ZWx5IGFyZSBub3Qgc2lnbmlmaWNhbnQuIEJ1dCB0aGVyZSBhcmUgc2lnbmlmaWNhbnQgY29ycmVsYXRpb25zIGFjcm9zcyBhbGwgcGFydGljaXBhbnRzLiBJIHdvcnJ5IGl0IGlzIGNhdXNlZCBieSBIZWFyaW5nTm92aWNlLCB0aG91Z2guLi4KCmBgYHtyIGNvcnJlbGF0aW9uIHRhYmxlfQpyZXN1bHRzMyA8LSB0cmliYmxlKAogIH4gbWV0cmljLCB+IEFvQVNMY29ycmVsYXRpb25SdmFsdWUsIH4gUHZhbHVlLAogICJnaXN0LWZ3IiwgLTAuMzIsIDAuMDE5LAogICJnaXN0LXJ2IiwgLTAuMzksIDAuMDA0LAogICJsZXgtZnciLCAtMC4wOCwgMC41NjcsCiAgImxleC1ydiIsIC0wLjM0LCAwLjAxNAopCnJlc3VsdHMzCmBgYAoKIyBSYWluJ3MgTm90ZXMKQWJvdXQgQWR1bHRzOgoKLUkgdGhpbmsgSSB3YW50IHRvIHdyaXRlIGl0IHVwIGFzIGFuIEFOQ09WQSwgd2l0aCBkaXJlY3Rpb24gaW5jbHVkZWQuICBBbmQgTFNEIGNvbXBhcmlzb25zIGluc3RlYWQgb2YgVHVrZXkuICAoSSB3aWxsIGRvIG15IG93biBjb3JyZWN0aW9ucykKLVlvdSBvZnRlbiBoYXZlIG9uZSBsaW5lcnMgc3VtbWFyaXppbmcgcmVzdWx0cywgaW4gYWxsIHRhYnMsIHRob3NlIGFyZSBuaWNlLCBrZWVwIHRoZW0gY29taW5nLgotKElmIHlvdSBoYXZlIHJlYXNvbnMgdG8gcHJlc2VudCBhbnl0aGluZyBvdGhlciB0aGFuIHRoZSBBTkNPVkEsIHB1dCB0aGF0IGluIHlvdXIgcmVzdWx0cyB0YWIpCiAKSSB0aGluayBpZiB3ZSBkbyBpdCB0aGlzIHdheSB0aGVuIHdlIGdldCBhIHJlYWxseSBpbXBvcnRhbnQgc3RvcnkgdG8gdGVsbDogIFRoYXQgdGhlICpjcml0aWNhbCogQW9BIGN1dG9mZiBpcyBiZWxvdyA0IHZzIGFib3ZlIDQgeWVhcnMgb2YgYWdlICh0d28gZ3JvdXBzIDAtNCB2cyA0LTEzKS4gIFRoaXMgc3VnZ2VzdCBlYXJseSBBU0wgaXMgaW1wb3J0YW50LiAgCgpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIEdpc3QgYXMgYmlub21pYWwgbG9naXQtbGluayBmdW5jdGlvbiBtb2RlbApnaXN0X2dsbW0gPC0gZ2xtZXIoZ2lzdCB+IGRpcmVjdGlvbiAqIG1haW5ncm91cCArICgxfGlkKSArICgxfHN0b3J5KSwgZGF0YSA9IGZ1bGxkYXRhLCBmYW1pbHk9Ymlub21pYWwgKGxpbms9ImxvZ2l0IikpCnN1bW1hcnkoZ2lzdF9nbG1tKQpgYGAKCiMgVGVybmFyeSBQbG90cwoKTGV0J3MgbWFrZSB0cmlhbmdsZSBwbG90cy4gIldoYXQ/IiB5b3Ugc2F5LiBSZWFkIG9uLiAKCmBgYHtyIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShnZ3Rlcm4pCmZ1bGxkYXRhICU+JSAKICBnZ3Rlcm4oYWVzKHggPSBleWVzLCB5ID0gbW91dGgsIHogPSBuZWNrKSkgKyBmYWNldF9ncmlkKGRpcmVjdGlvbiB+IG1haW5ncm91cCkgKyBzdGF0X2RlbnNpdHlfdGVybihnZW9tPSdwb2x5Z29uJywgYWVzKGZpbGw9Li5sZXZlbC4uKSwgYmlucz00KSArIGdlb21fcG9pbnQoY29sb3IgPSAid2hpdGUiLCBhbHBoYSA9IDAuNSkgKyB0aGVtZV9idygpCgpmdWxsZGF0YSAlPiUgCiAgZ2d0ZXJuKGFlcyh4ID0gZXllcywgeSA9IG1vdXRoLCB6ID0gbmVjaykpICsgZmFjZXRfZ3JpZChkaXJlY3Rpb24gfiBtYWluZ3JvdXApICsgZ2VvbV9jb25maWRlbmNlX3Rlcm4oYnJlYWtzID0gYyguNSksIGNvbG9yID0gInJlZCIpICsgZ2VvbV9wb2ludCgpICsgdGhlbWVfYncoKQpgYGAKCg==